问题
After performing filtering on Recyclerview items that are fetched through json. It's opening the wrong item when I clicked after filtering the list. Suppose A,B,C,D are in my list, and when I filter for B and click on it - it shows the wrong item (like: A,C,D) but not B. How to fix this?
MainActivity.java:
public class exit_Activity extends AppCompatActivity implements MyAdapter.OnItemClickListener {
String Show_url = "https://retrieve.php";
public static final String EXTRA_ID = "id";
public static final String EXTRA_V = "v";
public static final String EXTRA_Name = "name";
public static final String EXTRA_t = "in";
public static final String EXTRA_o = "out";
public static final String EXTRA_date = "date";
public static final String EXTRA_yes = "yes";
RecyclerView removeView;
private AlertDialog alertDialog;
ProgressBar progressBar;
NetworkChangeListerner networkChangeListerner = new NetworkChangeListerner();
private SwipeRefreshLayout mSwipeRefreshLayout;
private ArrayList<Employee> mEmployeeList;
private MyAdapter myadapter;
TextInputEditText search;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exit_);
retrieveData();
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
///
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.refreshlayout);
mSwipeRefreshLayout.setColorSchemeResources(R.color.black, R.color.green, R.color.red);
progressBar = (ProgressBar) findViewById(R.id.progressbar);
Sprite FoldingCube = new Wave();
progressBar.setIndeterminateDrawable(FoldingCube);
//
search = findViewById(R.id.search);
//exit
removeView = findViewById(R.id.exit_entry);
removeView.setHasFixedSize(true);
removeView.setLayoutManager(new LinearLayoutManager(this));
mEmployeeList = new ArrayList<>();
myadapter = new MyAdapter(exit_Activity.this, mEmployeeList);
removeView.setAdapter(myadapter);
//end
search.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
filter(s.toString());
}
});
}
private void filter(String text) {
ArrayList<Employee> filteredList = new ArrayList<>();
for (Employee item : mEmployeeList) {
if (item.getVehicle_number().toLowerCase().contains(text.toLowerCase())) {
filteredList.add(item);
}
}
myadapter.filterList(filteredList);
}
public void retrieveData() {
StringRequest request = new StringRequest(Request.Method.POST, Show_url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
mEmployeeList.clear();
try {
JSONObject jsonObject = new JSONObject(response);
String sucess = jsonObject.getString("success");
JSONArray jsonArray = jsonObject.getJSONArray("user_data");
if (sucess.equals("1")) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
String id = object.getString("id");
String vehicle_number = object.getString("number");
String driver_name = object.getString("name");
String entry_time = object.getString("time");
String entry_date = object.getString("date");
String exit_time = object.getString("ttime");
String yes = object.getString("yes");
mEmployeeList.add(new Employee(id, number, name, time, date, ttime, yes));
}
myadapter.notifyDataSetChanged();
myadapter.setOnItemClickListener(exit_Activity.this);
progressBar.setVisibility(View.GONE);
mSwipeRefreshLayout.setRefreshing(false);
Toast.makeText(getApplicationContext(), "List Updated", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(exit_Activity.this, error.getMessage(), Toast.LENGTH_LONG).show();
error.printStackTrace();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(request);
}
}
@Override
public void onItemClick(int position) {
Intent ediIntent = new Intent(this, Edit_Activity.class);
Employee clickedItem = mEmployeeList.get(position);
ediIntent.putExtra(EXTRA_ID, clickedItem.getId());
ediIntent.putExtra(EXTRA_V, clickedItem.getnumber());
ediIntent.putExtra(EXTRA_Name, clickedItem.getname());
ediIntent.putExtra(EXTRA_date, clickedItem.getdate());
ediIntent.putExtra(EXTRA_t, clickedItem.gettime());
ediIntent.putExtra(EXTRA_o, clickedItem.getttime());
ediIntent.putExtra(EXTRA_yes, clickedItem.getYes());
startActivity(ediIntent);
}
Myadapter.class:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{
private Context mcontext;
private ArrayList<Employee> marrayListEmployee;
private OnItemClickListener mListener;
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
public MyAdapter(Context context, ArrayList<Employee> arrayListEmployee) {
mcontext = context;
marrayListEmployee = arrayListEmployee;
}
/* public MyAdapter(@NonNull Context context, List<Employee> arrayListEmployee) {
super(context, R.layout.custom_list_item,arrayListEmployee);
this.context = context;
this.arrayListEmployee = arrayListEmployee;
}
*/
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mcontext).inflate(R.layout.custom_list_item, parent, false);
MyViewHolder evh = new MyViewHolder(v);
return evh;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Employee currentItem = marrayListEmployee.get(position);
String tvID = currentItem.getId();
String tvName = currentItem.getnumber();
holder.tvID.setText(tvID);
holder.tvName.setText(tvName);
}
@Override
public int getItemCount() {
return marrayListEmployee.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView tvID;
public TextView tvName;
public MyViewHolder(View itemView) {
super(itemView);
tvID = itemView.findViewById(R.id.txt_id);
tvName = itemView.findViewById(R.id.number);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mListener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
mListener.onItemClick(position);
}
}
}
});
}
}
public void filterList(ArrayList<Employee> filteredList) {
marrayListEmployee = filteredList;
notifyDataSetChanged();
}
}
回答1:
You have to get element from the list that was changed after filter not the old list
private ArrayList<Employee> filteredList = new ArrayList<Employee>();
private void filter(String text) {
filteredList.clear();
for (Employee item : mEmployeeList) {
if (item.getVehicle_number().toLowerCase().contains(text.toLowerCase())) {
filteredList.add(item);
}
}
myadapter.filterList(filteredList);
}
@Override
public void onItemClick(int position) {
Intent ediIntent = new Intent(this, Edit_Activity.class);
if(filteredList.size() > 0) {
Employee clickedItem = filteredList.get(position);
} else {
Employee clickedItem = mEmployeeList.get(position);
}
...
}
回答2:
EDITED
Sorry I didn't see the correct answer marked...
I will not delete, use this to improve some things
Don't copy/paste code because it's not tested, try to understand the changes
In filter method you replaced marrayListEmployee with filteredList and in retrieveData method you didn set anything, just notified adapter
Adapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{
private Context mcontext;
private ArrayList<Employee> marrayListEmployee;
private OnItemClickListener mListener;
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
public MyAdapter(Context context, ArrayList<Employee> arrayListEmployee) {
mcontext = context;
marrayListEmployee = arrayListEmployee;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mcontext).inflate(R.layout.custom_list_item, parent, false);
return new MyViewHolder(v);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Employee currentItem = marrayListEmployee.get(position);
holder.tvID.setText(currentItem.getId());
holder.tvName.setText(currentItem.getnumber());
//TODO set setOnClickListener here instead in ViewHolder constructor
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mListener != null) {
int position = holder.getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
mListener.onItemClick(position);
}
}
}
});
}
@Override
public int getItemCount() {
return marrayListEmployee.size();
}
public void filterList(ArrayList<Employee> filteredList) {
marrayListEmployee = filteredList;
notifyDataSetChanged();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView tvID;
public TextView tvName;
public MyViewHolder(View itemView) {
super(itemView);
tvID = itemView.findViewById(R.id.txt_id);
tvName = itemView.findViewById(R.id.number);
}
}
}
Activity - onCreate
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......
removeView = findViewById(R.id.exit_entry);
removeView.setHasFixedSize(true);
removeView.setLayoutManager(new LinearLayoutManager(this));
mEmployeeList = new ArrayList<>();
removeView.setAdapter(new MyAdapter(this, mEmployeeList));
myadapter.setOnItemClickListener(this); //TODO set click listener here instead evrytime in retrieveData method
.........
}
RetrieveData data method
public void retrieveData() {
StringRequest request = new StringRequest(Request.Method.POST, Show_url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
mEmployeeList.clear();
try {
JSONObject jsonObject = new JSONObject(response);
String sucess = jsonObject.getString("success");
JSONArray jsonArray = jsonObject.getJSONArray("user_data");
if (sucess != null && sucess.equals("1")) { //check null
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
String id = object.getString("id");
String vehicle_number = object.getString("number");
String driver_name = object.getString("name");
String entry_time = object.getString("time");
String entry_date = object.getString("date");
String exit_time = object.getString("ttime");
String yes = object.getString("yes");
mEmployeeList.add(new Employee(id, number, name, time, date, ttime, yes));
}
//myadapter.notifyDataSetChanged(); // remove this,
//myadapter.setOnItemClickListener(exit_Activity.this); remove this, set it in onCreate method
//TODO you have to reset mEmployeeList (below) because you changed it by filtering
myadapter.filterList(mEmployeeList); // change method name to swapData()
progressBar.setVisibility(View.GONE);
mSwipeRefreshLayout.setRefreshing(false);
Toast.makeText(getApplicationContext(), "List Updated", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(exit_Activity.this, error.getMessage(), Toast.LENGTH_LONG).show();
error.printStackTrace();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(request);
}
filter method
private void filter(String text) {
if(text == null || text.isEmpty()) return;
ArrayList<Employee> filteredList = new ArrayList<>();
for (Employee item : mEmployeeList) {
if (item.getVehicle_number() == null) continue; // TODO check null
if (item.getVehicle_number().toLowerCase().contains(text.toLowerCase())) {
filteredList.add(item);
}
}
myadapter.filterList(filteredList); // change method name to swapData()
}
来源:https://stackoverflow.com/questions/65876114/after-filter-a-recyclerview-item-and-clicking-it-gives-wrong-item