如何使"Listview"上的选项根据"Searchview"上键入的内容导航到



当在searchview中键入字符时,我无法导航到下一个片段。例如,如果我在searchview中键入"Dog",并从Listview中选择Dog选项,它将引导我返回Homepage

但是,如果searchview中没有任何内容,就像在searchview中没有键入任何内容一样,则导航工作正常。例如,单击Listview中的Dog选项将导航到Dog片段。

当不点击searchview时,我似乎也无法使列表视图折叠。

我附上了一张图片作为我面临的问题的参考。

在下面的代码中,我使用默认的ArrayAdapter

图像参考

搜索视图.kt

//searchview
var user = arrayOf("Home","Dog","Cat","Hamster")

adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, user)
binding.categories.adapter = adapter
binding.searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
if (user.contains(query)) {
adapter.filter.filter(query)
} else {
Toast.makeText(this@MainActivity, "No Match found", Toast.LENGTH_LONG).show()
}
return false
}
override fun onQueryTextChange(newText: String): Boolean {
adapter.filter.filter(newText)
return false
}
})
val home = adapter.getItemId(0)
val cat = adapter.getItemId(1)
val hamster = adapter.getItemId(2)
val dog = adapter.getItemId(3)
binding.categories.setOnItemClickListener { parent, view, position, ID ->
when(ID){
home ->{navController.navigate(R.id.action_global_home2)
}
cat -> {navController.navigate(R.id.action_global_cat) }
hamster -> {navController.navigate(R.id.action_global_hamster)}
dog -> {navController.navigate(R.id.action_global_dog)
}
}
}

Searchview.xml

<androidx.drawerlayout.widget.DrawerLayout
.....       
<androidx.appcompat.widget.SearchView
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="30dp"
android:layout_marginBottom="16dp"
app:queryHint="Enter Search"
android:background="@drawable/searchview_background"
app:iconifiedByDefault="false"
app:queryBackground="@android:color/transparent"

>
</androidx.appcompat.widget.SearchView>
<!--Listview-->
<ListView
android:id="@+id/categories"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
tools:listitem="@layout/searchview_listitem"/>

.....
<androidx.drawerlayout.widget.DrawerLayout

getItemIdArrayAdapter所做的一切都是返回项目在显示列表中的位置-您可以在这个非常好的网站上查看来源:

@Override
public long getItemId(int position) {
return position;
}

它可以用于其他适配器实现(例如,ID是项目对应的数据库行(,但在这种情况下没有。

因此,因为你正在获取原始列表,并将它们的位置存储为homecat等,所以你的点击监听器最终实际上相当于:

when(position){
0 -> navController.navigate(R.id.action_global_home2)
1 -> navController.navigate(R.id.action_global_cat)
2 -> navController.navigate(R.id.action_global_hamster)
3 -> navController.navigate(R.id.action_global_dog)
}

position与它们在显示列表中的位置有关,而不是与数据集中的位置有关。所以当你过滤";狗,并且Dog是唯一显示的项目,其position0。单击它,它的ID(即位置记住(与第一个分支匹配,即带您进入主页的分支。


因此,您不能真正依赖position或默认的getItemId实现(这是一样的(来识别您的实际项目。最简单的解决方法是获取项目本身(在本例中为String(并与之进行比较:

when(adapter.getItem(position)){
"Home" -> navController.navigate(R.id.action_global_home2)
"Cat" -> navController.navigate(R.id.action_global_cat)
"Hamster" -> navController.navigate(R.id.action_global_hamster)
"Dog" -> navController.navigate(R.id.action_global_dog)
}

或者,如果你真的想使用索引,你可以在你的源数组中查找项目

val dataSet = user
// or you could create a list/array from inside the adapter with
// val dataSet = (0 until count).map(this::getItem)
when(dataSet.indexOf(adapter.getItem(position)){
0 -> navController.navigate(R.id.action_global_home2)
1 -> navController.navigate(R.id.action_global_cat)
2 -> navController.navigate(R.id.action_global_hamster)
3 -> navController.navigate(R.id.action_global_dog)
}

但这有点脆弱-它需要在两个不同的地方定义数据的顺序,即原始数组中的顺序和when匹配器中的顺序。(您已经遇到了这个问题——仓鼠when中的位置不对!(。使用String值可以确保匹配正确的项,除非您键入了错误,或者更改了原始数组中的文本,但没有更改匹配器。它们是独立的、不相连的价值观,因此没有任何保护措施。它很容易坏。

在定义数据时,最好将您的项目与标签目的地关联起来。由于ArrayAdapter通过对数组中包含的任何对象调用toString()来获得它显示的字符串,因此您可以在其中放入任何内容!你可以制作一个简单的类:

class Item(val name: String, val destination: Int) {
// we only want to display the name
override fun toString() = name
}

然后用它在同一个地方定义你的数据:

val items = arrayOf(
Item("Home", R.id.action_global_home2),
Item("Cat", R.id.action_global_cat),
Item("Hamster", R.id.action_global_hamster),
Item("Dog", R.id.action_global_dog)
)
adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, items)

然后,为了处理您的点击,您只需要获取点击位置Item,它的导航操作就在数据中!

binding.categories.setOnItemClickListener { _, _, position, _ ->
val item = adapter.getItem(position)
item?.let { navController.navigate(it.destination) }
// or item?.destination?.run(navController::navigate) - same thing!
}

你可以在enum class中完成所有这些,因为它是硬编码的,但这种方式允许你创建任意的Item,从数据库或互联网等加载数据,这可能是你最终想要做的。你可以把你想要的任何数据放在Item中,任何有用的!

相关内容

  • 没有找到相关文章

最新更新