From 2b96b3140dd6e3f34e731fb67227e5a8d2e02039 Mon Sep 17 00:00:00 2001 From: Finn M Glas Date: Sun, 21 Jun 2020 15:27:27 +0200 Subject: [PATCH 1/3] Create a working SearchView for the appslist - Add a `filter` method to `AppsRecyclerView` - Add a `SearchView` to layout --- .../launcher/list/apps/AppsRecyclerAdapter.kt | 40 +++++++++++++++---- .../launcher/list/apps/ListFragmentApps.kt | 31 ++++++++++++-- app/src/main/res/layout/list_apps.xml | 10 +++++ 3 files changed, 69 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/finnmglas/launcher/list/apps/AppsRecyclerAdapter.kt b/app/src/main/java/com/finnmglas/launcher/list/apps/AppsRecyclerAdapter.kt index e05e140..09dce18 100644 --- a/app/src/main/java/com/finnmglas/launcher/list/apps/AppsRecyclerAdapter.kt +++ b/app/src/main/java/com/finnmglas/launcher/list/apps/AppsRecyclerAdapter.kt @@ -13,8 +13,10 @@ import android.widget.PopupMenu import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.finnmglas.launcher.* -import com.finnmglas.launcher.libraries.* +import com.finnmglas.launcher.libraries.FontAwesome import com.finnmglas.launcher.list.intendedChoosePause +import java.util.* +import kotlin.collections.ArrayList /** * A [RecyclerView] (efficient scrollable list) containing all apps on the users device. @@ -30,6 +32,7 @@ class AppsRecyclerAdapter(val activity: Activity, RecyclerView.Adapter() { private val appsList: MutableList + private val appsListDisplayed: MutableList inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener { @@ -40,7 +43,7 @@ class AppsRecyclerAdapter(val activity: Activity, override fun onClick(v: View) { val pos = adapterPosition val context: Context = v.context - val appPackageName = appsList[pos].packageName.toString() + val appPackageName = appsListDisplayed[pos].packageName.toString() when (intention){ "view" -> { @@ -62,10 +65,10 @@ class AppsRecyclerAdapter(val activity: Activity, } override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) { - val appLabel = appsList[i].label.toString() - val appPackageName = appsList[i].packageName.toString() - val appIcon = appsList[i].icon - val isSystemApp = appsList[i].isSystemApp + val appLabel = appsListDisplayed[i].label.toString() + val appPackageName = appsListDisplayed[i].packageName.toString() + val appIcon = appsListDisplayed[i].icon + val isSystemApp = appsListDisplayed[i].isSystemApp viewHolder.textView.text = appLabel viewHolder.img.setImageDrawable(appIcon) @@ -127,7 +130,7 @@ class AppsRecyclerAdapter(val activity: Activity, return true } - override fun getItemCount(): Int { return appsList.size } + override fun getItemCount(): Int { return appsListDisplayed.size } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val inflater = LayoutInflater.from(parent.context) @@ -136,8 +139,11 @@ class AppsRecyclerAdapter(val activity: Activity, } init { - val pm: PackageManager = activity.packageManager appsList = ArrayList() + appsListDisplayed = ArrayList() + + val pm: PackageManager = activity.packageManager + val i = Intent(Intent.ACTION_MAIN, null) i.addCategory(Intent.CATEGORY_LAUNCHER) val allApps = pm.queryIntentActivities(i, 0) @@ -149,5 +155,23 @@ class AppsRecyclerAdapter(val activity: Activity, appsList.add(app) } appsList.sortBy { it.label.toString() } + appsListDisplayed.addAll(appsList) + } + + /** + * The function [filter] is used to search elements within this [RecyclerView]. + */ + fun filter(text: String) { + appsListDisplayed.clear() + if (text.isEmpty()) { + appsListDisplayed.addAll(appsList) + } else { + for (item in appsList) { + if (item.label.toString().toLowerCase(Locale.ROOT).contains(text.toLowerCase(Locale.ROOT))) { + appsListDisplayed.add(item) + } + } + } + notifyDataSetChanged() } } diff --git a/app/src/main/java/com/finnmglas/launcher/list/apps/ListFragmentApps.kt b/app/src/main/java/com/finnmglas/launcher/list/apps/ListFragmentApps.kt index 5504371..22ddb95 100644 --- a/app/src/main/java/com/finnmglas/launcher/list/apps/ListFragmentApps.kt +++ b/app/src/main/java/com/finnmglas/launcher/list/apps/ListFragmentApps.kt @@ -1,17 +1,19 @@ package com.finnmglas.launcher.list.apps +import android.graphics.Color import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.SearchView +import android.widget.TextView import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import com.finnmglas.launcher.R import com.finnmglas.launcher.UIObject -import com.finnmglas.launcher.list.intention -import com.finnmglas.launcher.list.forApp import com.finnmglas.launcher.dominantColor -import com.finnmglas.launcher.getSavedTheme +import com.finnmglas.launcher.list.forApp +import com.finnmglas.launcher.list.intention import kotlinx.android.synthetic.main.list_apps.* @@ -36,17 +38,38 @@ class ListFragmentApps : Fragment(), UIObject { override fun applyTheme() { list_apps_container.setBackgroundColor(dominantColor) + + val id: Int = list_apps_searchview.context.resources + .getIdentifier("android:id/search_src_text", null, null) + list_apps_searchview.findViewById(id).setTextColor(Color.WHITE) } override fun setOnClicks() { } override fun adjustLayout() { + + val appsRViewAdapter = AppsRecyclerAdapter(activity!!, intention, forApp) + // set up the list / recycler list_apps_rview.apply { // improve performance (since content changes don't change the layout size) setHasFixedSize(true) layoutManager = LinearLayoutManager(context) - adapter = AppsRecyclerAdapter(activity!!, intention, forApp) + adapter = appsRViewAdapter } + + list_apps_searchview.setOnQueryTextListener(object : SearchView.OnQueryTextListener { + + override fun onQueryTextSubmit(query: String): Boolean { + appsRViewAdapter.filter(query); + return false + } + + override fun onQueryTextChange(newText: String): Boolean { + appsRViewAdapter.filter(newText); + return false + } + + }) } } \ No newline at end of file diff --git a/app/src/main/res/layout/list_apps.xml b/app/src/main/res/layout/list_apps.xml index 0c711a4..b3decd4 100644 --- a/app/src/main/res/layout/list_apps.xml +++ b/app/src/main/res/layout/list_apps.xml @@ -2,6 +2,7 @@ @@ -12,6 +13,7 @@ android:layout_height="0dp" android:layout_marginStart="16dp" android:layout_marginLeft="16dp" + android:layout_marginTop="32dp" android:layout_marginEnd="16dp" android:layout_marginRight="16dp" android:scrollbars="vertical" @@ -20,4 +22,12 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + + \ No newline at end of file From 02ae80be68178b79b33ece0876141a68df17ace3 Mon Sep 17 00:00:00 2001 From: Finn M Glas Date: Sun, 21 Jun 2020 19:16:10 +0200 Subject: [PATCH 2/3] Auto-launch app if only one result is found As this behaviour seems more efficient. TODO: Add option to disable this --- .../launcher/list/apps/AppsRecyclerAdapter.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/java/com/finnmglas/launcher/list/apps/AppsRecyclerAdapter.kt b/app/src/main/java/com/finnmglas/launcher/list/apps/AppsRecyclerAdapter.kt index 09dce18..6b48cd2 100644 --- a/app/src/main/java/com/finnmglas/launcher/list/apps/AppsRecyclerAdapter.kt +++ b/app/src/main/java/com/finnmglas/launcher/list/apps/AppsRecyclerAdapter.kt @@ -8,6 +8,7 @@ import android.net.Uri import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.view.inputmethod.InputMethodManager import android.widget.ImageView import android.widget.PopupMenu import android.widget.TextView @@ -172,6 +173,16 @@ class AppsRecyclerAdapter(val activity: Activity, } } } + + // Launch apps automatically if only one result is found + // TODO: Add option to disable this + if (appsListDisplayed.size == 1) { + launch(appsListDisplayed[0].packageName.toString(), activity) + + val inputMethodManager = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager + inputMethodManager.hideSoftInputFromWindow(View(activity).windowToken, 0) + } + notifyDataSetChanged() } } From 53462d654bded53dbe03ddc508f55f373dd5522c Mon Sep 17 00:00:00 2001 From: Finn M Glas Date: Sun, 21 Jun 2020 21:22:59 +0200 Subject: [PATCH 3/3] Make sure it also looks good - Adjust colors / themes - Adjust layout - Expand it --- .../launcher/list/apps/AppsRecyclerAdapter.kt | 2 +- .../launcher/list/apps/ListFragmentApps.kt | 12 +++---- app/src/main/res/layout/list_apps.xml | 32 +++++++++++++------ app/src/main/res/values/styles.xml | 6 +++- 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/finnmglas/launcher/list/apps/AppsRecyclerAdapter.kt b/app/src/main/java/com/finnmglas/launcher/list/apps/AppsRecyclerAdapter.kt index 6b48cd2..b3cc908 100644 --- a/app/src/main/java/com/finnmglas/launcher/list/apps/AppsRecyclerAdapter.kt +++ b/app/src/main/java/com/finnmglas/launcher/list/apps/AppsRecyclerAdapter.kt @@ -176,7 +176,7 @@ class AppsRecyclerAdapter(val activity: Activity, // Launch apps automatically if only one result is found // TODO: Add option to disable this - if (appsListDisplayed.size == 1) { + if (appsListDisplayed.size == 1 && intention == "view") { launch(appsListDisplayed[0].packageName.toString(), activity) val inputMethodManager = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager diff --git a/app/src/main/java/com/finnmglas/launcher/list/apps/ListFragmentApps.kt b/app/src/main/java/com/finnmglas/launcher/list/apps/ListFragmentApps.kt index 22ddb95..2247723 100644 --- a/app/src/main/java/com/finnmglas/launcher/list/apps/ListFragmentApps.kt +++ b/app/src/main/java/com/finnmglas/launcher/list/apps/ListFragmentApps.kt @@ -1,12 +1,9 @@ package com.finnmglas.launcher.list.apps -import android.graphics.Color import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.SearchView -import android.widget.TextView import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import com.finnmglas.launcher.R @@ -38,10 +35,8 @@ class ListFragmentApps : Fragment(), UIObject { override fun applyTheme() { list_apps_container.setBackgroundColor(dominantColor) - - val id: Int = list_apps_searchview.context.resources - .getIdentifier("android:id/search_src_text", null, null) - list_apps_searchview.findViewById(id).setTextColor(Color.WHITE) + list_apps_searchview.setBackgroundColor(dominantColor) + list_apps_searchbar.setBackgroundColor(dominantColor) } override fun setOnClicks() { } @@ -58,7 +53,8 @@ class ListFragmentApps : Fragment(), UIObject { adapter = appsRViewAdapter } - list_apps_searchview.setOnQueryTextListener(object : SearchView.OnQueryTextListener { + list_apps_searchview.setOnQueryTextListener(object : + androidx.appcompat.widget.SearchView.OnQueryTextListener { override fun onQueryTextSubmit(query: String): Boolean { appsRViewAdapter.filter(query); diff --git a/app/src/main/res/layout/list_apps.xml b/app/src/main/res/layout/list_apps.xml index b3decd4..94f3fa3 100644 --- a/app/src/main/res/layout/list_apps.xml +++ b/app/src/main/res/layout/list_apps.xml @@ -7,27 +7,39 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + + + + - - + app:layout_constraintTop_toBottomOf="@id/list_apps_searchbar" /> \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 695101d..6c2b558 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -6,9 +6,13 @@ @color/finnmglasTheme_background_color @color/finnmglasTheme_background_color - @color/finnmglasTheme_accent_color + #888 @color/finnmglasTheme_text_color + @color/finnmglasTheme_text_color + @color/finnmglasTheme_text_color + #555 + @style/Widget.AppCompat.Button.Colored @color/finnmglasTheme_accent_color