为什么项目 select 在普通列表的 recyclerview 中不起作用,但在搜索列表中起作用?
Why item select doesn't work in recyclerview on normal list but works in search list?
我已经为存储在 firebase 数据库中的项目创建了数组列表。我能够在 recyclerview 中列出项目。甚至搜索也能正常工作。但是当涉及到单击 recyclerview 列表中的项目时,单击在搜索列表中有效,但在正常列表中无效。代码如下
public class MainActivity extends AppCompatActivity implements Adapter.SelectedProject {
DatabaseReference mDatabase;
ArrayList<projects> list;
RecyclerView PList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PList = findViewById(R.id.ProjList);
PList.setHasFixedSize(true);
mDatabase = FirebaseDatabase.getInstance().getReference().child("Projects");
}
@Override
protected void onStart() {
super.onStart();
if (mDatabase != null) {
mDatabase.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
list = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
list.add(ds.getValue(projects.class));
}
Adapter adapter = new Adapter(list, null);
PList.setAdapter(adapter);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Toast.makeText(MainActivity.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_home, menu);
MenuItem item = menu.findItem(R.id.search);
SearchView searchView = (SearchView) item.getActionView();
if (searchView != null) {
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
search(newText);
return true;
}
});
}
return super.onCreateOptionsMenu(menu);
}
private void search(String str) {
ArrayList<projects> sList = new ArrayList<>();
for (projects object : list) {
if (object.getPname().toLowerCase().contains(str.toLowerCase())) {
sList.add(object);
}
}
Adapter adapter = new Adapter(sList, this);
PList.setAdapter(adapter);
}
@Override
public void selectedProject(projects projects) {
startActivity(new Intent(MainActivity.this, InfoActivity.class));
}
}
适配器Class
public class Adapter extends RecyclerView.Adapter < Adapter.ProjViewHolder > {
private ArrayList < projects > list;
private SelectedProject selectedProject;
public Adapter(ArrayList < projects > list, SelectedProject selectedProject) {
this.list = list;
this.selectedProject = selectedProject;
}
@NonNull
@Override
public ProjViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.proj_list, parent, false);
return new ProjViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ProjViewHolder holder, int position) {
holder.prname.setText(list.get(position).getPname());
holder.prlocation.setText(list.get(position).getPlocation());
}
@Override
public int getItemCount() {
return list.size();
}
public interface SelectedProject {
void selectedProject(projects projects);
}
class ProjViewHolder extends RecyclerView.ViewHolder {
TextView prname, prlocation;
public ProjViewHolder(@NonNull View itemView) {
super(itemView);
prname = itemView.findViewById(R.id.FPName);
prlocation = itemView.findViewById(R.id.FPLocation);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectedProject.selectedProject(list.get(getAdapterPosition()));
}
});
}
}
}
选择在搜索适配器中被接受。
Adapter adapter = new Adapter(sList,this);
但普通适配器显示以下代码错误。
Adapter adapter = new Adapter(list,this);
但是如果我如下将其更改为 null,错误就会消失。
Adapter adapter = new Adapter(list,null);
但是当我点击时,应用程序关闭了。
请告诉我如何更正错误?
stackrace 详细信息
java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.volq.Adapter$SelectedProject.selectedProject(com.example.volq.projects)' on a null object reference
at com.example.volq.Adapter$ProjViewHolder.onClick(Adapter.java:68)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
请注意您为搜索设置适配器与正常设置适配器的方式之间的区别
Adapter adapter = new Adapter(sList, this); // `this`as the second parameter/listener is ok
但对于另一个:
Adapter adapter = new Adapter(list, null);
这里监听器为null,这个错误是有道理的:
java.lang.NullPointerException: Attempt to invoke interface method
'void
com.example.volq.Adapter$SelectedProject.selectedProject(com.example.volq.projects)'
on a null object reference
而不是 null,只需在 Activity 的 onStart()
回调中传递 MainActivity.this
:
Adapter adapter = new Adapter(list, MainActivity.this);
But normal adapter shows error for the below code.
Adapter adapter = new Adapter(list,this);
是因为this
在onDataChange()
回调里面没有引用MainActivity
,而是引用了ValueEventListener
我已经为存储在 firebase 数据库中的项目创建了数组列表。我能够在 recyclerview 中列出项目。甚至搜索也能正常工作。但是当涉及到单击 recyclerview 列表中的项目时,单击在搜索列表中有效,但在正常列表中无效。代码如下
public class MainActivity extends AppCompatActivity implements Adapter.SelectedProject {
DatabaseReference mDatabase;
ArrayList<projects> list;
RecyclerView PList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PList = findViewById(R.id.ProjList);
PList.setHasFixedSize(true);
mDatabase = FirebaseDatabase.getInstance().getReference().child("Projects");
}
@Override
protected void onStart() {
super.onStart();
if (mDatabase != null) {
mDatabase.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
list = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
list.add(ds.getValue(projects.class));
}
Adapter adapter = new Adapter(list, null);
PList.setAdapter(adapter);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Toast.makeText(MainActivity.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_home, menu);
MenuItem item = menu.findItem(R.id.search);
SearchView searchView = (SearchView) item.getActionView();
if (searchView != null) {
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
search(newText);
return true;
}
});
}
return super.onCreateOptionsMenu(menu);
}
private void search(String str) {
ArrayList<projects> sList = new ArrayList<>();
for (projects object : list) {
if (object.getPname().toLowerCase().contains(str.toLowerCase())) {
sList.add(object);
}
}
Adapter adapter = new Adapter(sList, this);
PList.setAdapter(adapter);
}
@Override
public void selectedProject(projects projects) {
startActivity(new Intent(MainActivity.this, InfoActivity.class));
}
}
适配器Class
public class Adapter extends RecyclerView.Adapter < Adapter.ProjViewHolder > {
private ArrayList < projects > list;
private SelectedProject selectedProject;
public Adapter(ArrayList < projects > list, SelectedProject selectedProject) {
this.list = list;
this.selectedProject = selectedProject;
}
@NonNull
@Override
public ProjViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.proj_list, parent, false);
return new ProjViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ProjViewHolder holder, int position) {
holder.prname.setText(list.get(position).getPname());
holder.prlocation.setText(list.get(position).getPlocation());
}
@Override
public int getItemCount() {
return list.size();
}
public interface SelectedProject {
void selectedProject(projects projects);
}
class ProjViewHolder extends RecyclerView.ViewHolder {
TextView prname, prlocation;
public ProjViewHolder(@NonNull View itemView) {
super(itemView);
prname = itemView.findViewById(R.id.FPName);
prlocation = itemView.findViewById(R.id.FPLocation);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectedProject.selectedProject(list.get(getAdapterPosition()));
}
});
}
}
}
选择在搜索适配器中被接受。
Adapter adapter = new Adapter(sList,this);
但普通适配器显示以下代码错误。
Adapter adapter = new Adapter(list,this);
但是如果我如下将其更改为 null,错误就会消失。
Adapter adapter = new Adapter(list,null);
但是当我点击时,应用程序关闭了。
请告诉我如何更正错误?
stackrace 详细信息
java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.volq.Adapter$SelectedProject.selectedProject(com.example.volq.projects)' on a null object reference
at com.example.volq.Adapter$ProjViewHolder.onClick(Adapter.java:68)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
请注意您为搜索设置适配器与正常设置适配器的方式之间的区别
Adapter adapter = new Adapter(sList, this); // `this`as the second parameter/listener is ok
但对于另一个:
Adapter adapter = new Adapter(list, null);
这里监听器为null,这个错误是有道理的:
java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.volq.Adapter$SelectedProject.selectedProject(com.example.volq.projects)' on a null object reference
而不是 null,只需在 Activity 的 onStart()
回调中传递 MainActivity.this
:
Adapter adapter = new Adapter(list, MainActivity.this);
But normal adapter shows error for the below code.
Adapter adapter = new Adapter(list,this);
是因为this
在onDataChange()
回调里面没有引用MainActivity
,而是引用了ValueEventListener