在GridView中过滤产品,OnItemClick传递不同的产品细节

时间:2018-04-07 17:15:04

标签: java android gridview filter onitemclicklistener

我正在使用GridView来展示产品。我的自定义适配器类我实现了过滤搜索,这允许我给出想要的结果。添加OnItemClick后,我意识到在过滤模式下,点击的项目会给我错误的细节。

我认为它与ViewHolder有关,它在customadapter中实现,并向用户发送错误的项目活动。为什么?我们来看看这张图: Strange beahaviour 它代表两种情况 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();
        }
    });

1 个答案:

答案 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
    }
});