RecyclerView筛选时的位置

huangapple go评论79阅读模式
英文:

RecyclerView position on filter

问题

以下是翻译后的代码部分:

SavedActivity.java

@Override
public boolean onQueryTextSubmit(String query) {
    return false;
}

@Override
public boolean onQueryTextChange(String newText) {
    String input = newText.toLowerCase();
    ArrayList<String> newList = new ArrayList<>();
    for (String addressname : DBaddress_name) {
        if (addressname.toLowerCase().contains(input)) {
            newList.add(addressname);
        }
    }
    customerAdapter.updateList(newList);
    return true;
}
}

CustomAdapter.java

class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {

    private Context context;
    private Activity activity;
    private ArrayList<String> address_id, address_timestamp, address, address_lat, address_long, address_name;

    private Animation recycler_anim;

    CustomAdapter(Activity activity, Context context, ArrayList<String> address_id, ArrayList<String> address_timestamp, ArrayList<String> address, ArrayList<String> address_lat, ArrayList<String> address_long, ArrayList<String> address_name) {
        this.activity = activity;
        this.context = context;
        this.address_id = address_id;
        this.address_timestamp = address_timestamp;
        this.address = address;
        this.address_lat = address_lat;
        this.address_long = address_long;
        this.address_name = address_name;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.my_row, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
        holder.address_id_txt.setText("Nº" + String.valueOf(address_id.get(position)));
        holder.address_timestamp_txt.setText(String.valueOf(address_timestamp.get(position)));
        holder.address_txt.setText(String.valueOf(address.get(position)));
        holder.address_lat_txt.setText("纬度:" + String.valueOf(address_lat.get(position)));
        holder.address_long_txt.setText("经度:" + String.valueOf(address_long.get(position)));
        holder.address_name_txt.setText(String.valueOf(address_name.get(position)));
        holder.recyclerViewLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int adapterPosition = holder.getAdapterPosition();
                Intent intent = new Intent(context, UpdateActivity.class);
                intent.putExtra("id", String.valueOf(address_id.get(adapterPosition)));
                intent.putExtra("address", String.valueOf(address.get(adapterPosition)));
                intent.putExtra("address_name", String.valueOf(address_name.get(adapterPosition)));
                activity.startActivityForResult(intent, 1);
            }
        });
    }

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

    public class MyViewHolder extends RecyclerView.ViewHolder {

        TextView address_id_txt, address_timestamp_txt, address_txt, address_lat_txt, address_long_txt, address_name_txt, address_distance_txt;
        LinearLayout recyclerViewLayout;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            address_id_txt = itemView.findViewById(R.id.address_id_txt);
            address_timestamp_txt = itemView.findViewById(R.id.address_timestamp_txt);
            address_txt = itemView.findViewById(R.id.address_address_txt);
            address_lat_txt = itemView.findViewById(R.id.address_lat_txt);
            address_long_txt = itemView.findViewById(R.id.address_long_txt);
            address_name_txt = itemView.findViewById(R.id.address_name_txt);
            address_distance_txt = itemView.findViewById(R.id.address_distance_txt);
            recyclerViewLayout = itemView.findViewById(R.id.recyclerViewLayout);
            recycler_anim = AnimationUtils.loadAnimation(context, R.anim.recycler_anim);
            recyclerViewLayout.setAnimation(recycler_anim);
        }
    }

    public void updateList(ArrayList<String> newList) {
        address_name = new ArrayList<>();
        address_name.addAll(newList);
        notifyDataSetChanged();
    }
}
英文:

I have a RecyclerView which displays CardView with a bunch of info from SQLite database, such as address, lat, long, etc. When I introduce a filter in activity to search by address_name, it doesn't quite filter correctly. It does filter by address_name, but the rest of the information, such as lat long etc. is being displayed from the first item in the list, rather than the one that should correspond to address_name.

I tried doing the following (you will see it in the onClickListener), however it doesn't help too:

int adapterPosition = holder.getAdapterPosition();

Any ideas how to display the position correctly?
Code Below. Thank you!!!

SavedActivity.java

    @Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
String input = newText.toLowerCase();
ArrayList&lt;String&gt; newList = new ArrayList&lt;&gt;();
for (String addressname : DBaddress_name) {
if (addressname.toLowerCase().contains(input)) {
newList.add(addressname);
}
}
customerAdapter.updateList(newList);
return true;
}
}

CustomAdapter.java

class CustomAdapter extends RecyclerView.Adapter&lt;CustomAdapter.MyViewHolder&gt; {
private Context context;
private Activity activity;
private ArrayList&lt;String&gt; address_id, address_timestamp, address, address_lat, address_long, address_name;
private Animation recycler_anim;
CustomAdapter(Activity activity, Context context, ArrayList address_id, ArrayList address_timestamp, ArrayList address, ArrayList address_lat, ArrayList address_long, ArrayList address_name)
{
this.activity = activity;
this.context = context;
this.address_id = address_id;
this.address_timestamp = address_timestamp;
this.address = address;
this.address_lat = address_lat;
this.address_long = address_long;
this.address_name = address_name;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.my_row, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
holder.address_id_txt.setText(&quot;N&#186;&quot; + String.valueOf(address_id.get(position)));
holder.address_timestamp_txt.setText(String.valueOf(address_timestamp.get(position)));
holder.address_txt.setText(String.valueOf(address.get(position)));
holder.address_lat_txt.setText(&quot;Lat: &quot; + String.valueOf(address_lat.get(position)));
holder.address_long_txt.setText(&quot;Long: &quot; + String.valueOf(address_long.get(position)));
holder.address_name_txt.setText(String.valueOf(address_name.get(position)));
holder.recyclerViewLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int adapterPosition = holder.getAdapterPosition();
Intent intent = new Intent(context, UpdateActivity.class);
intent.putExtra(&quot;id&quot;,String.valueOf(address_id.get(adapterPosition)));
intent.putExtra(&quot;address&quot;,String.valueOf(address.get(adapterPosition)));
intent.putExtra(&quot;address_name&quot;,String.valueOf(address_name.get(adapterPosition)));
activity.startActivityForResult(intent, 1);
}
});
}
@Override
public int getItemCount() {
return address_name.size(); //size method of any of the array - all the same
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView address_id_txt, address_timestamp_txt, address_txt, address_lat_txt, address_long_txt, address_name_txt, address_distance_txt;
LinearLayout recyclerViewLayout;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
address_id_txt = itemView.findViewById(R.id.address_id_txt);
address_timestamp_txt = itemView.findViewById(R.id.address_timestamp_txt);
address_txt = itemView.findViewById(R.id.address_address_txt);
address_lat_txt = itemView.findViewById(R.id.address_lat_txt);
address_long_txt = itemView.findViewById(R.id.address_long_txt);
address_name_txt = itemView.findViewById(R.id.address_name_txt);
address_distance_txt = itemView.findViewById(R.id.address_distance_txt);
recyclerViewLayout = itemView.findViewById(R.id.recyclerViewLayout);
//Animate RecyclerView
recycler_anim = AnimationUtils.loadAnimation(context, R.anim.recycler_anim);
recyclerViewLayout.setAnimation(recycler_anim);
}
}
public void updateList(ArrayList&lt;String&gt; newList){
address_name = new ArrayList&lt;&gt;();
address_name.addAll(newList);
notifyDataSetChanged();
}
}

答案1

得分: 1

你只是传递了 address_name 并在适配器内部更新了这个 List,这就是为什么其他值没有得到更新的原因,你必须也传递其他的 Lists 来正确更新它们。

英文:

You are just passing the address_name and updating this List inside your adapter, that's why the other values are not getting updated, You have to passs other Lists as well to update them properly.

答案2

得分: 1

你需要创建一个POJO类,其中包含用于在每个“RecyclerView”项中显示数据的字段;而不是将不同的列表传递给适配器,你只需要将一个包含这些POJO的单一列表传递给RecyclerView;这样可以正确地反映出任何筛选,因为所有列表都被合并成一个单一的列表。

所以,你需要用以下内容替换:

private ArrayList<MyPojo> items;

而且MyPojo类应该具有address_Idaddress_timestamplonglataddress_name字段,以及相应的setter和getter方法。

> 更新:还不太确定如何进行筛选?

你只需要将String转换为MyPojo实例,因此为了进行筛选,你需要创建一个MyPojo的列表,而不是String的列表,适配器也必须具有MyPojo列表。

@Override
public boolean onQueryTextChange(String newText) {
    String input = newText.toLowerCase();
    ArrayList<MyPojo> newList = new ArrayList<>();

    for (MyPojo pojo : myPojoList) {
        if (pojo.getAddressName().toLowerCase().contains(input)) {
            newList.add(pojo);
        }
    }
    customerAdapter.updateList(newList); // 应该接受MyPojo作为参数,而不是String
    return true;
}
英文:

You need to create a POJO class that holds fields for the data you want to display in each RecyclerView item; and instead of passing in different lists to the adapter, you can just pass in a single list of this POJO to the RecyclerView; this will reflect any filtration correctly as all the lists are consolidated into a single list.

So, you've to replace the below

private ArrayList&lt;String&gt; address_id, address_timestamp, address, address_lat, address_long, address_name;

With

private ArrayList&lt;MyPojo&gt; items;

and MyPojo class should have the address_Id, address_timestamp, long, lat, address_name fields with setters and getters.

> UPDATE: not quite sure how to filter still?

You just need to migrate Strings to MyPojo instances, so for filtration purpose you need to create a list of MyPojo not list of Strings, and the adapter has to have MyPojo list as well.

@Override
public boolean onQueryTextChange(String newText) {
String input = newText.toLowerCase();
// ArrayList&lt;String&gt; newList = new ArrayList&lt;&gt;();
ArrayList&lt;MyPojo&gt; newList = new ArrayList&lt;&gt;();
for (MyPojo pojo : myPojoList) {
if (pojo.getAddressName().toLowerCase().contains(input)) {
newList.add(pojo);
}
}
customerAdapter.updateList(newList); // should accept MyPojo as a paramter not a String
return true;
}

huangapple
  • 本文由 发表于 2020年8月14日 23:35:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/63415828.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定