Android onQueryTextChange 不显示 UI 更改
Posted
技术标签:
【中文标题】Android onQueryTextChange 不显示 UI 更改【英文标题】:Android onQueryTextChange not showing UI changes 【发布时间】:2020-10-21 06:04:23 【问题描述】:当我开始输入我的android.widget.SearchView
时,我能够找到输入文本的匹配项,并看到我的Filter
来自我的Adapter
,它扩展了BaseAdapter
,确实找到了结果,但是,我在输入时实际上并没有看到建议的列表。
这是我所拥有的:
@Override
public boolean onCreateOptionsMenu(Menu menu)
super.onCreateOptionsMenu(menu);
MenuItem searchItem = menu.add(Menu.NONE, R.id.search_card, 1, R.string.search_card);
searchItem.setIcon(R.drawable.search);
searchItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
LinearLayout searchLayout = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.search_view, null);
SearchView searchView = searchLayout.findViewById(R.id.searchVieww);
searchItem.setActionView(searchView);
//this will be a dynamic list in the end, but just wanna get it to work first...
List<ListViewItem> suggestionList = new ArrayList<>();
suggestionList.add(new ListViewItem("abc", "123"));
suggestionList.add(new ListViewItem("apple", "345"));
ListViewAdapter adapter = new ListViewAdapter(suggestionList);
ListView listView = searchLayout.findViewById(R.id.searchViewList);
listView.setAdapter(adapter);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener()
@Override
public boolean onQueryTextSubmit(String word)
searchCardsForWord(word.trim());
searchView.setIconified(true); //first call to clear search bar
searchView.setIconified(true); //second call to close search bar
return true;
@Override
public boolean onQueryTextChange(String word)
adapter.getFilter().filter(word);
Log.d("DEBUG", "query text filter: " + adapter.getCount());// the count of this is NOT zero when I type in 'a'
return false;
);
...adding other MenuItems
return true;
适配器
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import com.boredofnothing.flashcard.databinding.ListViewItemBinding;
import java.util.ArrayList;
import java.util.List;
public class ListViewAdapter extends BaseAdapter implements Filterable
private List<ListViewItem> itemList;
private List<ListViewItem> itemListFull;
private LayoutInflater inflater;
ListViewAdapter(List<ListViewItem> itemList)
this.itemList = itemList;
itemListFull = new ArrayList<>(itemList);
@Override
public int getCount()
return itemList.size();
@Override
public ListViewItem getItem(int position)
return itemList.get(position);
@Override
public long getItemId(int position)
return position;
@Override
public Filter getFilter()
return filter;
private Filter filter = new Filter()
@Override
protected FilterResults performFiltering(CharSequence constraint)
List<ListViewItem> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0)
filteredList.addAll(itemListFull);
else
String filterPattern = constraint.toString().toLowerCase().trim();
for (ListViewItem item : itemListFull)
if (item.getText1().toLowerCase().contains(filterPattern)
|| item.getText2().toLowerCase().contains(filterPattern))
filteredList.add(item);
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
itemList.clear();
itemList.addAll((List) results.values);
notifyDataSetChanged();
;
@Override
public View getView(int position, View convertView, final ViewGroup parent)
if (inflater == null)
inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ListViewItemBinding listViewItemBinding = ListViewItemBinding.inflate(inflater);
listViewItemBinding.textView1.setText(itemList.get(position).getText1());
listViewItemBinding.textView2.setText(itemList.get(position).getText2());
return listViewItemBinding.getRoot();
search_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:focusableInTouchMode="true"
android:orientation="vertical">
<SearchView
android:id="@+id/searchVieww"
android:layout_
android:layout_
android:queryHint="Input word to search"></SearchView>
<ListView
android:id="@+id/searchViewList"
android:layout_
android:layout_
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:padding="8dp"
android:scrollbars="none" />
</LinearLayout>
list_view_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_
android:layout_marginBottom="4dp"
app:cardCornerRadius="4dp">
<RelativeLayout
android:layout_
android:layout_
android:layout_margin="4dp">
<TextView
android:id="@+id/text_view1"
android:layout_
android:layout_
android:layout_alignParentTop="true"
android:textColor="@android:color/black"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="@+id/text_view2"
android:layout_
android:layout_
android:layout_below="@+id/text_view1"
android:layout_marginStart="8dp"
android:textSize="15sp" />
</RelativeLayout>
</android.support.v7.widget.CardView>
在选择 SearchView 之前:
选择 SerachView 后:
输入“a”后:
最后,如果输入的单词/字符匹配或包含在我的suggestionList
中,我希望看到Cardviews
中的ListView
。
【问题讨论】:
你能发布你的 ListViewAdapter 吗?你是如何在你的适配器中实现过滤器的? @Gautam 我更新了我的帖子。过滤器只是检查输入的单词/字符是否存在于现在硬编码的列表中(这最终将是一个动态列表,但我只是想让它先工作) 如何将 search_view 添加到您的活动中?我假设此布局未绑定到您的活动 LinearLayout searchLayout = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.search_view, null);您必须将其添加到您的活动布局中才能显示结果 【参考方案1】:我只是在我的活动布局中添加 ListView
private SearchView searchView;
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.search_view);
searchView = findViewById(R.id.searchVieww);
listView = findViewById(R.id.searchViewList);
【讨论】:
很抱歉,问了这么一个琐碎的问题,您究竟添加了哪一行来使其正常工作? @mrnoobynoob 我已经用 sn-p 代码更新了上面的答案 在我的情况下,我实际上最终做了: ViewGroup rootLayout = findViewById(android.R.id.content); rootLayout.addView(searchLayout);但是,由于您的原始评论帮助我解决了我的问题,因此我仍会将其标记为我接受的答案。【参考方案2】:问题在于您发布结果的方式。
把itemList.clear();
改成
itemList = (List) results.values
发生的事情是,一旦您清除,所有对象都具有相同的引用,因此所有数据都丢失了,您看不到任何结果。
【讨论】:
不幸的是,我仍然得到与该更改相同的输出...我在 UI 上没有看到任何建议的列表,但我确实看到它仍然从过滤器中获得正确的结果.. . 我建议您在调用 notifyDataSetChanged 之前调试发布结果中列表的大小。如果您的列表中有项目并且您正在通知,那么您将在 UI 上看到结果以上是关于Android onQueryTextChange 不显示 UI 更改的主要内容,如果未能解决你的问题,请参考以下文章
在ListView中搜索特定描述时,SearchView不会刷新