RecyclerView+onClickListener+searchView显示错误的结果



基本上,我的代码是关于在recyclerView上显示用户数据的,&当被点击时,将指向显示该特定用户的更多数据的活动。

如果我不使用searchView,onClickListener可以正常工作。它意味着正确的数据。

然而,当使用searchView时,当单击第一个结果时,它总是获取在我输入任何searchView查询之前显示的recyclerView的第一个项目的数据,依此类推,用于位置2、3、4…

适配器类

public class OwnerAdapter extends RecyclerView.Adapter<OwnerAdapter.ViewHolder> {
private final RecyclerInterface recyclerInterface;
private ArrayList<Owners> ownerList;

public OwnerAdapter(ArrayList<Owners> ownerList, RecyclerInterface recyclerInterface){
this.recyclerInterface = recyclerInterface;
this.ownerList = ownerList;
}
public void setFilteredList(ArrayList<Owners> filteredList) {
this.ownerList = filteredList;
notifyDataSetChanged();
}
@NonNull
@Override
public OwnerAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.owner_recycler_row, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull OwnerAdapter.ViewHolder holder, int position) {
int resource = R.drawable.ic_baseline_person_24;
String name=ownerList.get(position).getOwner_name();
int owner_num = ownerList.get(position).getOwner_number();
String category = ownerList.get(position).getCategory();
holder.setData(resource,name,owner_num,category);
}
@Override
public int getItemCount() {
return ownerList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private ImageView imageView;
private TextView tvName, tvOwner_num, tvCategory;
public ViewHolder(@NonNull View itemView) {
super(itemView);
imageView=itemView.findViewById(R.id.imageview1);
tvName=itemView.findViewById(R.id.tvName);
tvOwner_num=itemView.findViewById(R.id.tvOwner_num);
tvCategory=itemView.findViewById(R.id.tvCategory);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (recyclerInterface != null) {
int pos = getAdapterPosition();
if (pos != RecyclerView.NO_POSITION){
recyclerInterface.onRecyclerClick(pos);
}
}
}
});
}
public void setData(int resource, String name, int owner_num, String category) {
imageView.setImageResource(resource);
tvName.setText(name);
tvOwner_num.setText(Integer.toString(owner_num));
tvCategory.setText(category);

}
}

} 

ViewOwners类(显示回收器视图(

public class ViewOwnerDetails extends AppCompatActivity implements RecyclerInterface {
RecyclerView recyclerView;
LinearLayoutManager layoutManager;
OwnerAdapter ownerAdapter;
ArrayList<Owners> ownerList = new ArrayList<>();
ArrayList<Owners> filteredList = new ArrayList<>();
private SearchView searchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.owner_recylcer_view);
new ViewOwnerDetails.Async().execute();
searchView = findViewById(R.id.searchView);
searchView.clearFocus();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
filteredList.clear();
filterList(newText);
return true;
}
});


}
class Async extends AsyncTask<Void, Void, Void> {
ProgressDialog pd;
@Override
protected void onPreExecute() { //before completing task
//loading message
super.onPreExecute();
pd = new ProgressDialog(ViewOwnerDetails.this);
pd.setMessage("Loading");
pd.show();
}
@Override
protected Void doInBackground(Void... voids) { //
load(); //load data to userList
return null;
}
@Override
protected void onPostExecute(Void aVoid) { //after completing task
initRecyclerView();
pd.dismiss();
}

}
public void load() {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://0104-acrs.mysql.database.azure.com:3306/azuredb", "VSVP", "VVSP0104!");
Statement statement = conn.createStatement();
ResultSet rs = statement.executeQuery("SELECT * FROM owner_data O INNER JOIN category C on O.catId = C.cat_id;");
while (rs.next()) {
String category = rs.getString("cat_name"), owner_name = rs.getString("owner_name");
int owner_num = rs.getInt("owner_num");
Boolean enabled = rs.getBoolean("isEnabled");
Owners owner = new Owners(owner_name, category, enabled, owner_num);
ownerList.add(owner);
Log.i("hi", "load: " + ownerList);
}
} catch (Exception e) {
Log.i("hi", "ERROR: " + e.getMessage());
}
}
private void initRecyclerView() {
recyclerView = findViewById(R.id.recyclerView);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
ownerAdapter = new OwnerAdapter(ownerList, this);
recyclerView.setAdapter(ownerAdapter);
ownerAdapter.notifyDataSetChanged();
}
public void onRecyclerClick(int position) {
Intent intent = new Intent(ViewOwnerDetails.this, ViewFullOwnerDetails.class);
if(searchView.toString().isEmpty()) {
intent.putExtra("NAME", ownerList.get(position).getOwner_name());
intent.putExtra("OWNER_NUM", ownerList.get(position).getOwner_number());
intent.putExtra("CATEGORY", ownerList.get(position).getCategory());
intent.putExtra("ENABLED", ownerList.get(position).isEnabled());
} else if(!searchView.toString().isEmpty()){
intent.putExtra("NAME", filteredList.get(position).getOwner_name());
intent.putExtra("OWNER_NUM", filteredList.get(position).getOwner_number());
intent.putExtra("CATEGORY", filteredList.get(position).getCategory());
intent.putExtra("ENABLED", filteredList.get(position).isEnabled());
}
startActivity(intent);
}
private void filterList(String text) {
for(Owners o : ownerList){
if(o.getOwner_name().toLowerCase().contains(text.toLowerCase())){
filteredList.add(o);
}
}
if(filteredList.isEmpty()) {
Toast.makeText(this, "No results found", Toast.LENGTH_SHORT).show();
} else {
ownerAdapter.setFilteredList(filteredList);
}
}
}

ViewFullOwnerInfo类(点击recyclerView项后使用(

public class ViewFullOwnerDetails extends AppCompatActivity {
TextView tvTitle, tvName, tvOwner_num, tvCategory, tvMember;
Button btBack, btEdit, btDeleteOwner, btView;
ArrayList<String> associatedList = new ArrayList<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.full_owner_details);
initComponents();
intentData();
new asyncsetUpAssociatedList().execute();
btBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(ViewFullOwnerDetails.this, ViewOwnerDetails.class);
startActivity(intent);
}
});
btDeleteOwner.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
deleteConfirmationOwner();
}
});
btEdit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(ViewFullOwnerDetails.this, ViewOwnerDetails.class);
startActivity(intent);
}
});
btView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
viewDialog(associatedList);
}
});

}
public void intentData() {
String name = getIntent().getStringExtra("NAME");
int owner_num = getIntent().getIntExtra("OWNER_NUM", 0);
String category = getIntent().getStringExtra("CATEGORY");
Boolean enabled = getIntent().getBooleanExtra("ENABLED", false);

tvTitle.setText("FULL INFORMATION");
tvName.setText(name);
tvOwner_num.setText(String.valueOf(owner_num));
tvCategory.setText(category);

if (enabled.toString() == "false") {
tvMember.setText("Membership Disabled");
} else if (enabled.toString() == "true") {
tvMember.setText("Membership Enabled");
}

}
private void initComponents() {
tvTitle = (TextView) findViewById(R.id.tvTitle);
tvName = (TextView) findViewById(R.id.tvName);
tvOwner_num = (TextView) findViewById(R.id.tvCategory);
tvCategory = (TextView) findViewById(R.id.tvOwner_num);
tvMember = (TextView) findViewById(R.id.tvMember);
btBack = (Button) findViewById(R.id.btBack);
btDeleteOwner = (Button) findViewById(R.id.buttonDeleteOwner);
btEdit = (Button) findViewById(R.id.btResolve);
btView = (Button) findViewById(R.id.btViewVehicles);
}
private void viewDialog(List<String> associatedList) {
String output = "";
if (associatedList.isEmpty()) {
output = "List empty";
} else {
for (int i = 0; i < associatedList.size(); i++) {
String vehicle = associatedList.get(i);
output += vehicle + "n";
}
}
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("ASSOCIATED VEHICLES: n" + output)
.setPositiveButton("Close", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
private void deleteConfirmationOwner() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to delete this Owner? It will delete all related vehicles also")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
new ViewFullOwnerDetails.asyncDeleteOwner().execute();
Intent intent = new Intent(ViewFullOwnerDetails.this, ViewOwnerDetails.class);
startActivity(intent);
Toast.makeText(ViewFullOwnerDetails.this, "Delete Succesful!", Toast.LENGTH_LONG).show();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
class asyncDeleteOwner extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... voids) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("url", "user", "pass");
String query = String.format("DELETE FROM owner_data WHERE owner_num = '%d'", Integer.parseInt(tvOwner_num.getText().toString()));
PreparedStatement statement = conn.prepareStatement(query);
statement.executeUpdate();

} catch (Exception e) {

}
return null;
}
}
class asyncsetUpAssociatedList extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("url", "pass", "user");
Statement statement = conn.createStatement();
//String query = String.format("SELECT * FROM vehicle_data V INNER JOIN owner_data O on O.owner_num = V.owner_num WHERE V.owner_num = '%d'", Integer.parseInt(tvOwner_num.getText().toString()));
ResultSet rs = statement.executeQuery("SELECT * FROM owner_data O INNER JOIN category C on O.catId = C.cat_id;");
while (rs.next()) {
String reg_num = rs.getString("reg_num");
associatedList.add(reg_num);
}
} catch (Exception e) {
Log.i("v", "Error: " + e.getMessage());
}
return null;
}
}
}

当我点击recyclerView item without search query时出错:

2022-08-01 18:13:39.119 26727-26727/? E/.example.acrs3: Unknown bits set in runtime_flags: 0x8000
2022-08-01 18:13:39.828 26727-26727/com.example.acrs30 E/RecyclerView: No adapter attached; skipping layout
2022-08-01 18:13:41.039 26727-26727/com.example.acrs30 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.acrs30, PID: 26727
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:437)
at com.example.acrs30.ViewOwnerDetails.onRecyclerClick(ViewOwnerDetails.java:131)
at com.example.acrs30.OwnerAdapter$ViewHolder$1.onClick(OwnerAdapter.java:73)
at android.view.View.performClick(View.java:7125)
at android.view.View.performClickInternal(View.java:7102)
at android.view.View.access$3500(View.java:801)
at android.view.View$PerformClick.run(View.java:27336)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

使用searchView时,当单击第一个结果时,它总是获取在我输入任何searchView查询之前显示的recyclerView的第一个项目的数据,依此类推,用于位置2,3,4…

这意味着在搜索项目时,您的recyclerView列表没有得到正确更新。您在搜索视图中显示的列表与您在单击时更改的列表不同。

public void onRecyclerClick(int position) {
Intent intent = new Intent(ViewOwnerDetails.this, ViewFullOwnerDetails.class);
intent.putExtra("NAME", ownerList.get(position).getOwner_name());
intent.putExtra("OWNER_NUM", ownerList.get(position).getOwner_number());
intent.putExtra("CATEGORY", ownerList.get(position).getCategory());
intent.putExtra("ENABLED", ownerList.get(position).isEnabled());
startActivity(intent);
}

因此,这里的问题是您正在访问ownerList的第一个项目,该项目与筛选列表不同。因此,为了获得正确的项目,您应该访问已筛选的列表,而不是ownerList。您可以初始化整个活动的filteredList,然后单击即可使用recyclerView。如果搜索视图为空,则可以访问ownerList中的项目;如果不是,则可以从筛选列表中访问项目。

在您的OwnerAdapter中,您应该将逻辑移出ViewHolder构造函数。数据绑定和逻辑实现应该在onBindViewHolder方法中进行:

@Override
public void onBindViewHolder(@NonNull OwnerAdapter.ViewHolder holder, int position) {
...
holder.itemView.setOnCLickListener(view ->
recyclerInterface.onRecyclerClick(position);
);
}

ViewHolder构造函数仅用于onCreateViewHolder初始化与其关联的ViewHolderViewsonBindViewHolderViewHolder与实际数据关联。在这些数据中,适配器中的ViewHolder有一个新的position,它提供了访问列表中实际项目的方法。

相关内容

  • 没有找到相关文章

最新更新