Skip to content

Commit

Permalink
feat: search/filter packages/activities
Browse files Browse the repository at this point in the history
  • Loading branch information
butzist committed Dec 30, 2023
1 parent e3cebb1 commit d44a376
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 7 deletions.
27 changes: 26 additions & 1 deletion app/src/main/java/de/szalkowski/activitylauncher/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SearchView
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import dagger.hilt.android.AndroidEntryPoint
import de.szalkowski.activitylauncher.databinding.ActivityMainBinding
import de.szalkowski.activitylauncher.services.SettingsService
import de.szalkowski.activitylauncher.ui.ActionBarSearch
import de.szalkowski.activitylauncher.ui.DisclaimerDialogFragment
import javax.inject.Inject

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
class MainActivity() : AppCompatActivity(), ActionBarSearch {

private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityMainBinding
Expand All @@ -41,9 +43,32 @@ class MainActivity : AppCompatActivity() {
setupActionBarWithNavController(navController, appBarConfiguration)
}


override var onActionBarSearchListener: ((String) -> Unit)? = null
private var actionBarSearchView: SearchView? = null
override var actionBarSearchText: String
get() = actionBarSearchView?.query?.toString().orEmpty()
set(value) { actionBarSearchView?.setQuery(value, false) }

override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu)

val searchView = menu.findItem(R.id.search).actionView as SearchView
actionBarSearchView = searchView
searchView.queryHint = getText(R.string.filter_hint)
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
onActionBarSearchListener?.invoke(query.orEmpty())
return true
}

override fun onQueryTextChange(query: String?): Boolean {
onActionBarSearchListener?.invoke(query.orEmpty())
return true
}
})

return true
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package de.szalkowski.activitylauncher.ui

interface ActionBarSearch {
var actionBarSearchText: String
var onActionBarSearchListener: ((String) -> Unit)?
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ class ActivityDetailsFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

val actionBar = activity as? ActionBarSearch
// FIXME just hide the search menu item, instead
actionBar?.actionBarSearchText = ""

binding.tiName.setText(activityInfo.name)
binding.tiPackage.setText(activityInfo.componentName.packageName)
binding.tiClass.setText(activityInfo.componentName.shortClassName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ class ActivityListAdapter @AssistedInject constructor(
fun create(packageName: String): ActivityListAdapter
}

private val activities = activityListService.getActivities(packageName)
private val allActivities = activityListService.getActivities(packageName)
private var filteredActivities = allActivities
var onItemClick: ((MyActivityInfo) -> Unit)? = null

inner class ViewHolder(viewItem: View) : RecyclerView.ViewHolder(viewItem) {
Expand All @@ -35,14 +36,27 @@ class ActivityListAdapter @AssistedInject constructor(
}
}

var filter: String = ""
set(value) {
field = value
filteredActivities = allActivities.filter { a ->
listOf(a.name, a.componentName.className).any {
it.contains(
field, ignoreCase = true
)
}
}
notifyDataSetChanged()
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val view = inflater.inflate(R.layout.list_item_package_list, parent, false)
return ViewHolder(view)
}

override fun getItemCount(): Int {
return activities.size
return filteredActivities.size
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
Expand All @@ -51,7 +65,7 @@ class ActivityListAdapter @AssistedInject constructor(
val tvPackage = view.findViewById<TextView>(R.id.tvPackage)
val ivIcon = view.findViewById<ImageView>(R.id.ivIcon)

val item = activities[position]
val item = filteredActivities[position]
holder.item = item
tvName.text = if (item.isPrivate) {
"(${item.name})"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ class ActivityListFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

val actionBar = activity as? ActionBarSearch
activityListAdapter.filter = actionBar?.actionBarSearchText.orEmpty()
actionBar?.onActionBarSearchListener = { search ->
activityListAdapter.filter = search
}

activityListAdapter.onItemClick = {
val action = ActivityListFragmentDirections.actionSelectActivity(it.componentName)
findNavController().navigate(action)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import javax.inject.Inject
class PackageListAdapter @Inject constructor(packageListService: PackageListService) :
RecyclerView.Adapter<PackageListAdapter.ViewHolder>() {

private val packages = packageListService.packages
private val allPackages = packageListService.packages
private var filteredPackages = allPackages

var onItemClick: ((MyPackageInfo) -> Unit)? = null

inner class ViewHolder(viewItem: View) : RecyclerView.ViewHolder(viewItem) {
Expand All @@ -27,14 +29,27 @@ class PackageListAdapter @Inject constructor(packageListService: PackageListServ
}
}

var filter: String = ""
set(value) {
field = value
filteredPackages = allPackages.filter { p ->
listOf(p.name, p.packageName).any {
it.contains(
field, ignoreCase = true
)
}
}
notifyDataSetChanged()
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val view = inflater.inflate(R.layout.list_item_package_list, parent, false)
return ViewHolder(view)
}

override fun getItemCount(): Int {
return packages.size
return filteredPackages.size
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
Expand All @@ -43,7 +58,7 @@ class PackageListAdapter @Inject constructor(packageListService: PackageListServ
val tvPackage = view.findViewById<TextView>(R.id.tvPackage)
val ivIcon = view.findViewById<ImageView>(R.id.ivIcon)

val item = packages[position]
val item = filteredPackages[position]
holder.item = item
tvName.text = item.name
tvPackage.text = item.packageName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ class PackageListFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

val actionBar = activity as? ActionBarSearch
packageListAdapter.filter = actionBar?.actionBarSearchText.orEmpty()
actionBar?.onActionBarSearchListener = { search ->
packageListAdapter.filter = search
}

packageListAdapter.onItemClick = {
val action = PackageListFragmentDirections.actionSelectPackage(it.packageName)
findNavController().navigate(action)
Expand Down

0 comments on commit d44a376

Please sign in to comment.