Add activity search to Android test app (#3275)
This commit is contained in:
@@ -6,9 +6,11 @@ import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Resources.NotFoundException
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@@ -35,6 +37,7 @@ import java.util.*
|
||||
class FeatureOverviewActivity : AppCompatActivity() {
|
||||
private lateinit var recyclerView: RecyclerView
|
||||
private var sectionAdapter: FeatureSectionAdapter? = null
|
||||
private var featureAdapter: FeatureAdapter? = null
|
||||
private var features: List<Feature>? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -50,7 +53,7 @@ class FeatureOverviewActivity : AppCompatActivity() {
|
||||
override fun onItemClicked(recyclerView: RecyclerView?, position: Int, view: View?) {
|
||||
if (sectionAdapter!!.isSectionHeaderPosition(position).not()) {
|
||||
val itemPosition = sectionAdapter!!.getConvertedPosition(position)
|
||||
val feature = features!![itemPosition]
|
||||
val feature = featureAdapter!!.getItem(itemPosition)
|
||||
startFeature(feature)
|
||||
}
|
||||
}
|
||||
@@ -86,6 +89,7 @@ class FeatureOverviewActivity : AppCompatActivity() {
|
||||
if (featuresList.isNullOrEmpty()) {
|
||||
return
|
||||
}
|
||||
featureAdapter = FeatureAdapter(features!!)
|
||||
val sections: MutableList<FeatureSectionAdapter.Section> = ArrayList()
|
||||
var currentCat = ""
|
||||
for (i in features!!.indices) {
|
||||
@@ -95,12 +99,11 @@ class FeatureOverviewActivity : AppCompatActivity() {
|
||||
currentCat = category
|
||||
}
|
||||
}
|
||||
|
||||
sectionAdapter = FeatureSectionAdapter(
|
||||
this,
|
||||
R.layout.section_main_layout,
|
||||
R.id.section_text,
|
||||
FeatureAdapter(features!!)
|
||||
featureAdapter!!
|
||||
)
|
||||
sectionAdapter!!.setSections(sections.toTypedArray())
|
||||
recyclerView.adapter = sectionAdapter
|
||||
@@ -163,6 +166,56 @@ class FeatureOverviewActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
// Add SearchView to the app bar
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_feature_overview, menu)
|
||||
val searchItem = menu.findItem(R.id.action_search)
|
||||
val searchView = searchItem.actionView as SearchView
|
||||
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||
return false // No action on submit
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
filterFeatures(newText)
|
||||
return true
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
// Filter the features based on the search query
|
||||
private fun filterFeatures(query: String?) {
|
||||
val filteredFeatures = if (query.isNullOrEmpty()) {
|
||||
features // Show full list if query is empty
|
||||
} else {
|
||||
features?.filter { it.getLabel().contains(query, ignoreCase = true) }
|
||||
}
|
||||
updateAdapter(filteredFeatures)
|
||||
}
|
||||
|
||||
// Update the adapter with filtered features
|
||||
private fun updateAdapter(filteredFeatures: List<Feature>?) {
|
||||
if (filteredFeatures.isNullOrEmpty()) {
|
||||
featureAdapter?.update(emptyList())
|
||||
sectionAdapter?.setSections(emptyArray())
|
||||
sectionAdapter?.notifyDataSetChanged()
|
||||
return
|
||||
}
|
||||
val sections: MutableList<FeatureSectionAdapter.Section> = ArrayList()
|
||||
var currentCat = ""
|
||||
for (i in filteredFeatures.indices) {
|
||||
val category = filteredFeatures[i].category
|
||||
if (currentCat != category) {
|
||||
sections.add(FeatureSectionAdapter.Section(i, category))
|
||||
currentCat = category
|
||||
}
|
||||
}
|
||||
featureAdapter?.update(filteredFeatures)
|
||||
sectionAdapter?.setSections(sections.toTypedArray())
|
||||
sectionAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val KEY_STATE_FEATURES = "featureList"
|
||||
}
|
||||
|
||||
@@ -12,12 +12,11 @@ import org.maplibre.android.testapp.utils.FontCache
|
||||
/**
|
||||
* Adapter used for FeatureOverviewActivity.
|
||||
*
|
||||
*
|
||||
* Adapts a Feature to a visual representation to be shown in a RecyclerView.
|
||||
*
|
||||
*/
|
||||
class FeatureAdapter(private val features: List<Feature>) :
|
||||
class FeatureAdapter(private var features: List<Feature>) :
|
||||
RecyclerView.Adapter<FeatureAdapter.ViewHolder>() {
|
||||
|
||||
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
var labelView: TextView
|
||||
var descriptionView: TextView
|
||||
@@ -32,8 +31,7 @@ class FeatureAdapter(private val features: List<Feature>) :
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view =
|
||||
LayoutInflater.from(parent.context).inflate(R.layout.item_main_feature, parent, false)
|
||||
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_main_feature, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
@@ -45,4 +43,13 @@ class FeatureAdapter(private val features: List<Feature>) :
|
||||
override fun getItemCount(): Int {
|
||||
return features.size
|
||||
}
|
||||
|
||||
fun update(newFeatures: List<Feature>) {
|
||||
features = newFeatures
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun getItem(position: Int): Feature {
|
||||
return features[position]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#333333"
|
||||
android:alpha="0.6">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
|
||||
</vector>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 515 B |
Binary file not shown.
|
After Width: | Height: | Size: 350 B |
Binary file not shown.
|
After Width: | Height: | Size: 638 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_search"
|
||||
android:icon="@drawable/ic_search"
|
||||
android:title="@string/search"
|
||||
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||
app:showAsAction="always|collapseActionView" />
|
||||
</menu>
|
||||
@@ -7,4 +7,5 @@
|
||||
<string name="category_benchmark">Benchmark</string>
|
||||
<string name="activity_benchmark_world_tour">World Tour Benchmark</string>
|
||||
<string name="description_world_tour_benchmark">Writes out avg. fps and 1% fps after world tour with .flyTo()</string>
|
||||
<string name="search">Search</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user