过滤 RecyclerView 项目并单击它后会给出错误的项目
After Filter a RecyclerView item and clicking it gives wrong item
对通过 json 获取的 Recyclerview 项目执行过滤后。当我在筛选列表后单击时,它打开了错误的项目。假设 A、B、C、D 在我的列表中,当我过滤 B 并单击它时 - 它显示了错误的项目(如:A、C、D)而不是 B。如何解决这个问题?
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();
}
}
您必须从过滤后更改的列表中获取元素,而不是旧列表
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);
}
...
}
已编辑
抱歉,我没有看到标记为正确答案...
我不会删除,用这个来完善一些东西
不要copy/paste编码,因为它没有经过测试,尝试理解变化
在 filter 方法中,您将 marrayListEmployee 替换为 filteredList,在 retrieveData 方法中,您没有设置任何内容,只是通知了适配器
适配器
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 数据方法
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);
}
过滤方法
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()
}
对通过 json 获取的 Recyclerview 项目执行过滤后。当我在筛选列表后单击时,它打开了错误的项目。假设 A、B、C、D 在我的列表中,当我过滤 B 并单击它时 - 它显示了错误的项目(如:A、C、D)而不是 B。如何解决这个问题?
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();
}
}
您必须从过滤后更改的列表中获取元素,而不是旧列表
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);
}
...
}
已编辑
抱歉,我没有看到标记为正确答案...
我不会删除,用这个来完善一些东西
不要copy/paste编码,因为它没有经过测试,尝试理解变化
在 filter 方法中,您将 marrayListEmployee 替换为 filteredList,在 retrieveData 方法中,您没有设置任何内容,只是通知了适配器
适配器
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 数据方法
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);
}
过滤方法
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()
}