Merge pull request #55 from finnmglas/feature/search-appslist

Make appslist searchable
This commit is contained in:
Finn M Glas 2020-06-21 22:10:55 +02:00 committed by GitHub
commit b33ce52ccc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 94 additions and 14 deletions

View file

@ -8,13 +8,16 @@ import android.net.Uri
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.ImageView import android.widget.ImageView
import android.widget.PopupMenu import android.widget.PopupMenu
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.finnmglas.launcher.* import com.finnmglas.launcher.*
import com.finnmglas.launcher.libraries.* import com.finnmglas.launcher.libraries.FontAwesome
import com.finnmglas.launcher.list.intendedChoosePause 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. * A [RecyclerView] (efficient scrollable list) containing all apps on the users device.
@ -30,6 +33,7 @@ class AppsRecyclerAdapter(val activity: Activity,
RecyclerView.Adapter<AppsRecyclerAdapter.ViewHolder>() { RecyclerView.Adapter<AppsRecyclerAdapter.ViewHolder>() {
private val appsList: MutableList<AppInfo> private val appsList: MutableList<AppInfo>
private val appsListDisplayed: MutableList<AppInfo>
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
View.OnClickListener { View.OnClickListener {
@ -40,7 +44,7 @@ class AppsRecyclerAdapter(val activity: Activity,
override fun onClick(v: View) { override fun onClick(v: View) {
val pos = adapterPosition val pos = adapterPosition
val context: Context = v.context val context: Context = v.context
val appPackageName = appsList[pos].packageName.toString() val appPackageName = appsListDisplayed[pos].packageName.toString()
when (intention){ when (intention){
"view" -> { "view" -> {
@ -62,10 +66,10 @@ class AppsRecyclerAdapter(val activity: Activity,
} }
override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) { override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
val appLabel = appsList[i].label.toString() val appLabel = appsListDisplayed[i].label.toString()
val appPackageName = appsList[i].packageName.toString() val appPackageName = appsListDisplayed[i].packageName.toString()
val appIcon = appsList[i].icon val appIcon = appsListDisplayed[i].icon
val isSystemApp = appsList[i].isSystemApp val isSystemApp = appsListDisplayed[i].isSystemApp
viewHolder.textView.text = appLabel viewHolder.textView.text = appLabel
viewHolder.img.setImageDrawable(appIcon) viewHolder.img.setImageDrawable(appIcon)
@ -127,7 +131,7 @@ class AppsRecyclerAdapter(val activity: Activity,
return true return true
} }
override fun getItemCount(): Int { return appsList.size } override fun getItemCount(): Int { return appsListDisplayed.size }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context) val inflater = LayoutInflater.from(parent.context)
@ -136,8 +140,11 @@ class AppsRecyclerAdapter(val activity: Activity,
} }
init { init {
val pm: PackageManager = activity.packageManager
appsList = ArrayList() appsList = ArrayList()
appsListDisplayed = ArrayList()
val pm: PackageManager = activity.packageManager
val i = Intent(Intent.ACTION_MAIN, null) val i = Intent(Intent.ACTION_MAIN, null)
i.addCategory(Intent.CATEGORY_LAUNCHER) i.addCategory(Intent.CATEGORY_LAUNCHER)
val allApps = pm.queryIntentActivities(i, 0) val allApps = pm.queryIntentActivities(i, 0)
@ -149,5 +156,33 @@ class AppsRecyclerAdapter(val activity: Activity,
appsList.add(app) appsList.add(app)
} }
appsList.sortBy { it.label.toString() } 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)
}
}
}
// Launch apps automatically if only one result is found
// TODO: Add option to disable this
if (appsListDisplayed.size == 1 && intention == "view") {
launch(appsListDisplayed[0].packageName.toString(), activity)
val inputMethodManager = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(View(activity).windowToken, 0)
}
notifyDataSetChanged()
} }
} }

View file

@ -8,10 +8,9 @@ import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.finnmglas.launcher.R import com.finnmglas.launcher.R
import com.finnmglas.launcher.UIObject 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.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.* import kotlinx.android.synthetic.main.list_apps.*
@ -36,17 +35,37 @@ class ListFragmentApps : Fragment(), UIObject {
override fun applyTheme() { override fun applyTheme() {
list_apps_container.setBackgroundColor(dominantColor) list_apps_container.setBackgroundColor(dominantColor)
list_apps_searchview.setBackgroundColor(dominantColor)
list_apps_searchbar.setBackgroundColor(dominantColor)
} }
override fun setOnClicks() { } override fun setOnClicks() { }
override fun adjustLayout() { override fun adjustLayout() {
val appsRViewAdapter = AppsRecyclerAdapter(activity!!, intention, forApp)
// set up the list / recycler // set up the list / recycler
list_apps_rview.apply { list_apps_rview.apply {
// improve performance (since content changes don't change the layout size) // improve performance (since content changes don't change the layout size)
setHasFixedSize(true) setHasFixedSize(true)
layoutManager = LinearLayoutManager(context) layoutManager = LinearLayoutManager(context)
adapter = AppsRecyclerAdapter(activity!!, intention, forApp) adapter = appsRViewAdapter
} }
list_apps_searchview.setOnQueryTextListener(object :
androidx.appcompat.widget.SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
appsRViewAdapter.filter(query);
return false
}
override fun onQueryTextChange(newText: String): Boolean {
appsRViewAdapter.filter(newText);
return false
}
})
} }
} }

View file

@ -2,10 +2,32 @@
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/list_apps_container" android:id="@+id/list_apps_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/list_apps_searchbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.SearchView
android:id="@+id/list_apps_searchview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8sp"
android:iconifiedByDefault="false"
app:iconifiedByDefault="false"
app:queryHint="Search Applications"
app:searchHintIcon="@android:drawable/ic_menu_search"
app:searchIcon="@android:drawable/ic_menu_search" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/list_apps_rview" android:id="@+id/list_apps_rview"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -18,6 +40,6 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toBottomOf="@id/list_apps_searchbar" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -6,9 +6,13 @@
<item name="colorPrimaryDark">@color/finnmglasTheme_background_color</item> <item name="colorPrimaryDark">@color/finnmglasTheme_background_color</item>
<item name="android:colorBackground">@color/finnmglasTheme_background_color</item> <item name="android:colorBackground">@color/finnmglasTheme_background_color</item>
<item name="colorAccent">@color/finnmglasTheme_accent_color</item> <item name="colorAccent">#888</item>
<item name="android:textColor">@color/finnmglasTheme_text_color</item> <item name="android:textColor">@color/finnmglasTheme_text_color</item>
<item name="android:textColorSecondary">@color/finnmglasTheme_text_color</item>
<item name="android:textColorPrimary">@color/finnmglasTheme_text_color</item>
<item name="android:textColorHint">#555</item>
<item name="android:buttonStyle">@style/Widget.AppCompat.Button.Colored</item> <item name="android:buttonStyle">@style/Widget.AppCompat.Button.Colored</item>
<item name="colorButtonNormal">@color/finnmglasTheme_accent_color</item> <item name="colorButtonNormal">@color/finnmglasTheme_accent_color</item>