我有一个 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/