过滤recyclerview后获取位置

时间:2019-01-12 22:44:21

标签: android filter android-recyclerview adapter

我有一个recyclerview和一个搜索字段。 如果未对回收站进行过滤,请点击打开所选项目的核心详细信息,但在过滤回收站后,打开错误的详细信息。 适配器:

公共类AllProductReyclerAdapter扩展了RecyclerView.Adapter {

private BaseActivity mContext;
private OnClickItem mInterface;
private  List<Produse> dataList;

public AllProductReyclerAdapter(BaseActivity con, List<Produse> mainCat, OnClickItem _interface) {

    if(con!=null) {
        mContext = con;
        mInterface=_interface;
        dataList=mainCat;
    }
}

@Override
public int getItemCount() {
    return dataList.size();
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_category_items, parent, false);
    ViewHolder vh = new ViewHolder(v);


    return vh;
}

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {

    holder.tvCatMain.setText("Denumire :"+dataList.get(position).getDenumire());
    holder.tvCode.setText("Code :"+dataList.get(position).getCod());
    holder.tvDeposit.setText("Depozit :"+dataList.get(position).getDepozit());
    holder.tvCant.setText("Cant :"+dataList.get(position).getCant());
    holder.tvDate.setText(dataList.get(position).getPicture());
    if (dataList.get(position).getPicture()!=null)
        Picasso.get().load("http://mysite/test/img/"+dataList.get(position).getProcesare()+" "+dataList.get(position).getCuloare()+".jpg").into(holder.ivItem);

    if (dataList.get(position).getPicture()!=null)
        Picasso.get()
                .load("http://mysite/test/img/"+dataList.get(position).getProcesare()+" "+dataList.get(position).getCuloare()+".jpg")
                .placeholder(R.drawable.placeholder)
                .error(R.drawable.placeholder)
                .into(holder.ivItem);

      holder.linMain.setTag(dataList.get(holder.getAdapterPosition()));

    holder.linMain.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mInterface.onListItemClick(view.getId(),position);

        }
    });

}



public class ViewHolder extends RecyclerView.ViewHolder {
    public LinearLayout linMain;
    public ImageView ivItem;
    public TextView tvCatMain,tvCode,tvDeposit,tvCant,tvDate;

    public ViewHolder(View view) {
        super(view);

        tvCatMain = view.findViewById(R.id.tvCatMain);
        ivItem = view.findViewById(R.id.ivItem);
        tvCode = view.findViewById(R.id.tvCode);
        tvDeposit = view.findViewById(R.id.tvDeposit);
        tvCant = view.findViewById(R.id.tvCant);
        tvDate = view.findViewById(R.id.tvDate);
        linMain = view.findViewById(R.id.linMain);


    }
}

public void filterList(ArrayList<Produse> filterdNames) {
    this.dataList = filterdNames;
    notifyDataSetChanged();
}

}

这是片段:

公共类DashboardFragment扩展了BaseFragment {

private RecyclerView rlProductList;
private View ivFilter;
private AllProductReyclerAdapter adapter;
private List<Produse> list=new ArrayList<>();
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_dashboard, container, false);
}

@Override
public void onViewCreated(@NonNull final View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    ((MainActivity)getActivity()).setPageTitle("Produse in stoc");
    rlProductList = view.findViewById(R.id.rlProductList);
    ivFilter = view.findViewById(R.id.ivFilter);
    ivFilter.setOnClickListener(this);
    rlProductList.setLayoutManager(new LinearLayoutManager(baseActivity, LinearLayoutManager.VERTICAL, false));
    adapter= new AllProductReyclerAdapter(baseActivity,  list, new OnClickItem() {
        @Override
        public void onListItemClick(Object o, int position) {
            Gson gson = new Gson();
            String result = gson.toJson( list.get(position));
            Bundle bundle=new Bundle();
            bundle.putString("details",result);
            ProductdetailsFragment fragment=new ProductdetailsFragment();
            fragment.setArguments(bundle);
            displayView(fragment);
        }
    });
    rlProductList.setAdapter(adapter);

    if (getArguments()!=null){
        if (getArguments().getString("search")!=null){

            list.clear();
            list.addAll(Constants.filteredProduct);
            adapter.notifyDataSetChanged();
        }

    }else{
        list.clear();
        list.addAll(Constants.allProduct);
        adapter.notifyDataSetChanged();

    }
    EditText etFilter = view.findViewById(R.id.etFilter);
    etFilter.addTextChangedListener(new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

            // TODO Auto-generated method stub


        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            // TODO Auto-generated method stub

        }

        @Override
        public void afterTextChanged(Editable s) {

            // TODO Auto-generated method stub
            if (adapter!=null){
                if (s.toString().length()>0)
                    filter(s.toString());
                else
                    adapter.notifyDataSetChanged();
            }
        }
    });
}

@Override
public void onClick(View view) {
    super.onClick(view);
    switch (view.getId()){
        case R.id.ivFilter:
            displayView(new ProductFilterFragment());
            break;

    }
}
private void filter(String names) {
    //new array list that will hold the filtered data
     ArrayList<Produse> filterdNames = new ArrayList<>();

    //looping through existing elements
    for (int i=0;i<list.size();i++) {
        //if the existing elements contains the search input
        if (list.get(i).getPicture()!=null&&list.get(i).getPicture().toLowerCase().contains(names.toLowerCase())) {
            //adding the element to filtered list
            filterdNames.add(list.get(i));
        }
    }

    //calling a method of the adapter class and passing the filtered list
    adapter.filterList(filterdNames);
}

}

2 个答案:

答案 0 :(得分:1)

我也遇到了这个问题,我发现的解决方案不是通过删除元素来过滤表。但是将筛选出的文章的高度设置为0。这样我就可以保持位置。

如果您无法用Java进行翻译,则代码位于kotlin中,请告诉我,我会为您提供帮助。

第1步:

添加此扩展名(或将其翻译为java方法):

var View.isRemovedHeight: Boolean
get() {
    return this.height == 0
}
set(value) {
    if (value) {
        val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0)
        this.layoutParams = params
    } else {
        val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
        this.layoutParams = params
    }
}

步骤2: 将此添加到您的适配器中

//Filtering implementation
private var textFilter: String = ""
private val filteredItems: ArrayList<Items> = ArrayList()

这:

// Filtering implementation
fun filter(text: String) {
    textFilter = text.toLowerCase()

    filteredCustomer.clear()
    filteredCustomer.addAll(items.filter { it.name.toLowerCase().contains(textFilter) || it.address.toLowerCase().contains(textFilter) || it.phone.toLowerCase().contains(textFilter) })
    notifyDataSetChanged()
}

fun notifyFilteringDataChanged() {
    filteredCustomer.addAll(items)
    filter(text = textFilter)
    notifyDataSetChanged()
}

第一种方法是过滤逻辑,第二种方法是刷新回收站。最好的事情是对方法notifyDataSetChanged进行覆盖,但是我们不能,因为它是最终方法。所以我创建了一个自定义的notifyDataChanged

第3步: 在布局xml中,在布局中放置一个ID,因为我们将删除其大小并将其设置为0

//Filtering implementation
val item = items[position]
holder.container.isRemovedHeight = !filteredItems.contains(item)

isRemovedHeight是上面的扩展,但是对于Java,您必须调用已翻译的方法

在活动中,每当您想要刷新回收视图中的数据时,请使用notifyFilteringDataChanged()方法,使所有内容都是最新的,就像这样:

adapter.notifyFilteringDataChanged()

在您习惯的情况下,请调用此方法:

adapter.filter(s.toString())

对不起,我的英语希望对您有帮助

Java

第1步:

public boolean removeHeight(View view, boolean isRemoved) {
    if(isRemoved) {
        LayoutParams params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
        view.setLayoutParams(params);
    } else {
        LayoutParams params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        view.setLayoutParams(params);
    }

    return isRemoved;
}

第2步:

private String textFilter = "";
private ArrayList<Item> filteredItems = ArrayList();

并且:

public void filter(String text){
    textFilter = text.toLowerCase();

    filteredCustomer.clear();
    filteredCustomer.addAll(items.stream().filter(i -> i.name.toLowerCase().contains(textFilter)));
    notifyDataSetChanged();
}

public void notifyFilteringDataChanged(){
    filteredCustomer.addAll(items);
    filter(textFilter);
    notifyDataSetChanged();
}

第3步:

Item item = items.get(position);
removeHeight(holder.container, !filteredItems.contains(item));

并且:

adapter.notifyFilteringDataChanged();

并且:

adapter.filter(s.toString());

答案 1 :(得分:0)

您不应在 onBindViewHolder 方法中设置单击侦听器。因为可能在数据集改变位置后捕获的值是错误的。 最佳实践是在 ViewHolder 中设置单击侦听器并使用 getAdapterPosition 获取位置。不要忘记将此值与 RecyclerView.No_Position 进行比较,如果不相等则调用您的回调。