RecyclerView搜索过滤器出错位置

时间:2016-11-22 16:55:02

标签: android

我使用RecyclerView,我对它进行过滤,我有问题

我搜索后,当我按下项目我错了位置没有我搜索它,请帮我解决这个问题

RecyclerView适配器

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

Context context;
List<listitem_gib> getDataAdapter;



public RecyclerViewAdapter(List<listitem_gib> getDataAdapter, Context context){

    super();

    this.getDataAdapter = getDataAdapter;
    this.context = context;

}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview_layout, parent, false);

    ViewHolder viewHolder = new ViewHolder(v,context,getDataAdapter);

    return viewHolder;
}

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

    listitem_gib getDataAdapter1 =  getDataAdapter.get(position);

    holder.name.setText(getDataAdapter1.getName());
    holder.num.setText(getDataAdapter1.getnum());
    Picasso.with(context).load("http://i-geeky.info/android/image/" + getDataAdapter1.getimg()).into(holder.img1);


}

@Override
public int getItemCount() {

    return getDataAdapter.size();
}

class ViewHolder extends RecyclerView.ViewHolder
            implements View.OnClickListener{

    public TextView name;
    public TextView num;
    public ImageView img1;

    ImageButton fav;

    Context context;
    List<listitem_gib> getDataAdapter;


    public ViewHolder(View itemView, Context context ,List<listitem_gib> getDataAdapter ) {

        super(itemView);
        itemView.setOnClickListener(this);
        this.getDataAdapter = getDataAdapter;
        this.context = context;
        this.fav= (ImageButton) itemView.findViewById(R.id.btn_fav);

        name = (TextView) itemView.findViewById(R.id.Main_Text) ;
        num = (TextView) itemView.findViewById(R.id.Second_Text) ;
        img1 = (ImageView) itemView.findViewById(R.id.img1) ;

    }


    @Override
    public void onClick(View v) {

        int position = getAdapterPosition();
        listitem_gib getDataAdapter =this.getDataAdapter.get(position);
        Intent intent = new Intent(this.context,Rewaya_info.class);
        intent.putExtra("name",getDataAdapter.getName());
        intent.putExtra("url",getDataAdapter.geturl());
        intent.putExtra("img",getDataAdapter.getimg());
        intent.putExtra("num",getDataAdapter.getnum());
        intent.putExtra("size",getDataAdapter.getsize());
        this.context.startActivity(intent);

    }
}
public void setFilter(List<listitem_gib> newList)
{
    getDataAdapter = new ArrayList<>();
    getDataAdapter.addAll(newList );
    notifyDataSetChanged();
}}

活动

@Override
public boolean onQueryTextChange(String newText) {

    newText = newText.toLowerCase();
    List<listitem_gib> newList = new ArrayList<>();
    for (listitem_gib list : GetDataAdapter1){
        String name = list.getName().toLowerCase();
        String name1 = list.getnum().toLowerCase();

        if (name.contains(newText) || name1.contains(newText)){
            newList.add(list);
        }
    }
    recyclerViewadapter.setFilter(newList);
    return true;
}

3 个答案:

答案 0 :(得分:3)

recyclerview重新使用现有元素并简单地将新数据绑定到这些元素 - 这可以防止需要创建的项目和被摧毁,而是被回收;)。

看一下ViewHolder的构造函数。在其中传入ViewHolders绑定到的初始数据列表。实际上,这会为您的初始列表创建静态绑定,不是已过滤的列表

public ViewHolder(View itemView, Context context ,List<listitem_gib> getDataAdapter ) {
    super(itemView);
    itemView.setOnClickListener(this);
    this.getDataAdapter = getDataAdapter; <-- this is stored in the viewholder
    ...
}

更好的方法是更好地利用onBindViewHolder的{​​{1}}。这将允许RecyclerViewAdapter在点击时使用适配器中的当前项目,如下所示:

ViewHolder

按如下方式更新您的@Override public void onBindViewHolder(final ViewHolder holder, final int position) { listitem_gib item = getDataAdapter.get(position); holder.bind(item); }

ViewHolder
  • 查看Get clicked item and its position in RecyclerView的答案,以提供更好的方法。
  • 如果可以,请尽量避免传递上下文。
  • 保留字段class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ private TextView name; private TextView num; private ImageView img1; ImageButton fav; Context context; private listitem_gib currentItem; //<-- allows this viewholder to keep a reference to the bound item public ViewHolder(View itemView, Context context) { //<-- no more adapter in constructor super(itemView); itemView.setOnClickListener(this); this.context = context; this.fav = (ImageButton) itemView.findViewById(R.id.btn_fav); name = (TextView) itemView.findViewById(R.id.Main_Text) ; num = (TextView) itemView.findViewById(R.id.Second_Text) ; img1 = (ImageView) itemView.findViewById(R.id.img1) ; } void bind (listitem_gib item) { //<--bind method allows the ViewHolder to bind to the data it is displaying name.setText(item.getName()); num.setText(item.getnum()); Picasso.with(this.context).load("http://i-geeky.info/android/image/" + item.getimg()).into(holder.img1); currentItem = item; //<-- keep a reference to the current item } @Override public void onClick(View v) { Intent intent = new Intent(this.context,Rewaya_info.class); intent.putExtra("name",currentItem.getName()); // <-- makes use of currentItem instead of adapter intent.putExtra("url",currentItem.geturl()); intent.putExtra("img",currentItem.getimg()); intent.putExtra("num",currentItem.getnum()); intent.putExtra("size",currentItem.getsize()); this.context.startActivity(intent); } }
祝你好运!

答案 1 :(得分:0)

您可以通过在Recycler适配器java中编辑OnItemClickListener来实现。

 itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mListener!=null){
                    int position = getAdapterPosition();
                    String name = songListFiltered.get(position).getText1();
                    for (int i=0; i <songList.size(); i++){
                        if (name.equals(songList.get(i).getText1())){
                            position=i;
                            break;
                        }
                    }
                    if (position!=RecyclerView.NO_POSITION){
                        mListener.OnItemClick(position);
                    }

                }
            }
        });

为了更好地理解,这是我完整的RecyclerAdapter.java

package com.jiunidengkw;

 import android.content.Context;
 import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.Filter;
  import android.widget.Filterable;
  import android.widget.TextView;

  import androidx.annotation.NonNull;
  import androidx.recyclerview.widget.RecyclerView;

   import java.util.ArrayList;
   import java.util.List;

   public class RecyclerAdapter extends                           RecyclerView.Adapter<RecyclerAdapter.ExampleViewHolder> implements Filterable {

private List<Item> songList;
private  Context context;
private List<Item> songListFiltered;
private List<Item> songListFull;
private OnItemClickListener mListener;

public interface  OnItemClickListener{
    void OnItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
    mListener=listener;
}






public class ExampleViewHolder extends RecyclerView.ViewHolder {
    TextView textView1;
    TextView textView2;

    ExampleViewHolder(final View itemView) {
        super(itemView);
        textView1 =(TextView) itemView.findViewById(R.id.text_view1);
        textView2 =(TextView) itemView.findViewById(R.id.text_view2);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mListener!=null){
                    int position = getAdapterPosition();
                    String name = songListFiltered.get(position).getText1();
                    for (int i=0; i <songList.size(); i++){
                        if (name.equals(songList.get(i).getText1())){
                            position=i;
                            break;
                        }
                    }
                    if (position!=RecyclerView.NO_POSITION){
                        mListener.OnItemClick(position);
                    }

                }
            }
        });
    }
}

public  RecyclerAdapter(Context context, List<Item> songList) {
    this.context = context;
    this.songListFiltered = songList;
    this.songList = songList;
}

@NonNull
@Override
public ExampleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item,
            parent, false);
    return new ExampleViewHolder(v);
}

@Override
public void onBindViewHolder(@NonNull ExampleViewHolder holder, int position) {

    holder.textView1.setText(songListFiltered.get(position).getText1());
    holder.textView2.setText(songListFiltered.get(position).getText2());
}

@Override
public int getItemCount() {

    return songListFiltered.size();
}

@Override
public Filter getFilter() {
    return exampleFilter;
}

private Filter exampleFilter = new Filter() {
    @Override
    protected FilterResults performFiltering(CharSequence charSequence) {
        String charString = charSequence.toString();

        if (charString.isEmpty()) {
            songListFiltered = songList;
        } else {
           ArrayList<Item> itemArrayList = new ArrayList<>();

            for (Item item : songList) {
                if (item.getText1().toLowerCase().contains(charString)||item.getText2().toLowerCase().contains(charString)) {
                    itemArrayList.add(item);

                }
            }
            songListFiltered =itemArrayList;
        }

        FilterResults item = new FilterResults();
        item.values = songListFiltered;

        return item;

    }

    @Override
    protected void publishResults(CharSequence charSequence, FilterResults item) {
       songListFiltered = (ArrayList<Item>) item.values;
        notifyDataSetChanged();
    }
};
   }

谢谢。

答案 2 :(得分:0)

我遇到了过滤结果的相同问题。问题看起来像这样

actualList = [4, 6, 3, 8, 9, 5, 2]

filteredList = [4, 3, 5, 2] // lets say filtering with <= 5

因此,当点击例如项目3 时,返回的位置将是1,而不是原始位置2。

所以一个简单的解决方案是(如果您使用的是arrayList或类似的方法)

// in onClick listener
val itemAtPosition = filteredList[position]
// actual item position can be obtained from actual list
val actualPosition = actualList.indexOf(itemAtPosition)

希望有人觉得它有用。