我有一个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);
}
}
答案 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 进行比较,如果不相等则调用您的回调。