android - 获取过滤recyclerview后的位置

标签 android filter android-recyclerview adapter

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

公共(public)类 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();
}

这是 fragment :

公共(public)类 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);
}

最佳答案

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

代码在 kotlin 中,如果你不能用 java 翻译它,请告诉我,我会帮助你。

第 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()
}

第一种方法是过滤逻辑,第二种方法是刷新recycleriew。最好的办法是重写 notifyDataSetChanged 方法,但我们不能这样做,因为它是 final方法。所以我创建了一个自定义的 notifyDataChanged

第 3 步: 在layout xml中,在layout中放一个id,因为我们会把它的size删掉,放0

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

isRemovedHeight是上面的扩展,但是对于java你必须调用翻译的方法

在您的 Activity 中,每当您想要刷新回收 View 中的数据时,请使用 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());

关于android - 获取过滤recyclerview后的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54164550/

相关文章:

api - Twitter Streaming API(过滤器方法)- 限制

android - RecyclerView + 具有不同图像大小的网格

Android:如何判断点击的画廊项目是否是中心项目?

javascript - 如何使用js过滤方法查找包含特定字符串的项目数

Android:应用程序构建和安装

css - 实现背景过滤器 : opacity(0%) in CSS

java - RecyclerView notifyItemChanged(position) 使应用程序崩溃并且没有使用 notifyDataSetChanged() 的动画

android - 滚动后 Recycler View 没有给出正确的位置

android - Gradle 构建错误,错误 :Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'

android - 如何解决数组越界异常?