我正在使用GridView
来展示产品。我的自定义适配器类我实现了过滤搜索,这允许我给出想要的结果。添加OnItemClick
后,我意识到在过滤模式下,点击的项目会给我错误的细节。
我认为它与ViewHolder
有关,它在customadapter
中实现,并向用户发送错误的项目活动。为什么?我们来看看这张图:
它代表两种情况
1)启动活动时,gridview
默认显示所有条目
2)使用过滤器搜索并显示结果时
以下是我的自定义适配器类的一部分:
@Override
public View getView(int position, View view, ViewGroup parent) {
Log.d(TAG, "getView: assigning all values to custom adapter");
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
ViewHolder viewHolder;
Product product= productList.get(position);
//Creating new fields
if (view == null) {
view = layoutInflater.inflate(R.layout.single_product_layout, parent, false);
viewHolder = new ViewHolder();
viewHolder.productName = view.findViewById(R.id.name);
viewHolder.productPrice = view.findViewById(R.id.price);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
//Set up textviews and image
viewHolder.productName.setText(product.getName());
viewHolder.productPrice.setText(product.getPrice());
return view;
}
static class ViewHolder {
TextView productName;
TextView productPrice;
}
这里是过滤搜索的代码,我把它保存在同一个主类(CustomAdapter)中:
@Override
public Filter getFilter() {
if (customFilter == null) {
customFilter = new CustomFilter();
}
return customFilter;
}
class CustomFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults filterResults = new FilterResults();
if (charSequence != null && charSequence.length() > 0) {
charSequence = charSequence.toString().toUpperCase();
List<Product> filters = new ArrayList<>();
for (int i = 0; i < tempList.size(); i++) {
if (tempList.get(i).getName().toUpperCase().contains(charSequence)) {
Product product = new Product( tempList.get(i).getName(), tempList.get(i).getPrice());
filters.add(product);
}
}
filterResults.count = filters.size();
filterResults.values = filters;
} else {
filterResults.count = tempList.size();
filterResults.values = tempList;
}
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
productList = (List<Product>) filterResults.values;
notifyDataSetChanged();
}
}
OnItemClick
代码:
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Product product = allProducts.get(i);
String name = product.getName();
String price = product.getPrice();
Intent intent = new Intent(context, ProductDetails.class);
intent.putExtra("name", name);
intent.putExtra("price", price);
startActivity(intent);
}
});
我想摆脱误导性的OnItemClick
beahviour,它会以错误的细节启动细节活动。
自定义搜索栏的实现:
final EditText searchBar = findViewById(R.id.search_product);
searchBar.addTextChangedListener(this);
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
Log.d(TAG, "onTextChanged: starting...");
this.productAdapter.getFilter().filter(charSequence);
}
@Override
public void afterTextChanged(Editable editable) {
}
清除按钮代码:
//Clear search bar
ImageView cancelClearSearch = findViewById(R.id.cancel_clear_search);
cancelClearSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
searchBar.setText("");
searchBar.clearFocus();
//Hide keyboard
InputMethodManager inputManager = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(searchBar.getWindowToken(), 0);
new DownloadProducts().execute();
}
});
答案 0 :(得分:2)
当你这样做时
productList = (List<Product>) filterResults.values;
适配器和活动中的列表开始指向内存中的两个单独列表,但过滤后的数据位于适配器使用的列表中,而不是将新列表分配给productList
使用
productList.clear();
productList.addAll((List<Product>) filterResults.values);
或替代选项是将adapterView
实例中的数据检索为
//Product product = allProducts.get(i);
Product product = (Product)adapterView.getAdapter().getItem(i);
// get associated adapter with list view ^^^^^^^^^
// get the item from adapter, using position ^^^^^^^^^^^
要在清除搜索edittext
后显示旧列表,只需将带有空字符串的过滤器应用为
//Clear search bar
ImageView cancelClearSearch = findViewById(R.id.cancel_clear_search);
cancelClearSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
this.productAdapter.getFilter().filter("");
searchBar.setText("");
searchBar.clearFocus();
//Hide keyboard
InputMethodManager inputManager = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(searchBar.getWindowToken(), 0);
//new DownloadProducts().execute(); no need to download data again
}
});