I have created arraylist for projects which is stored in firebase database. I was able to list the projects in recyclerview. Even search too works fine. But when it comes to clicking an item in the recyclerview list, the click works in search list but doesn't work in normal list. The code is given below
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));
}
}
Adapter 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()));
}
});
}
}
}
The selection is accepted in the search adapter.
Adapter adapter = new Adapter(sList,this);
But normal adapter shows error for the below code.
Adapter adapter = new Adapter(list,this);
But if i change this to null as below, the error goes off.
Adapter adapter = new Adapter(list,null);
But when I clicked, the app is closed.
Please let me know how to correct the error?
stackrace details
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$1.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)
Notice the difference between how you're setting your adapter for search vs normal
Adapter adapter = new Adapter(sList, this); // `this`as the second parameter/listener is ok
But for the other one:
Adapter adapter = new Adapter(list, null);
Here the listener is null, this error makes sense:
java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.volq.Adapter$SelectedProject.selectedProject(com.example.volq.projects)' on a null object reference
Instead of null, just pass MainActivity.this
in your Activity's onStart()
callback:
Adapter adapter = new Adapter(list, MainActivity.this);
But normal adapter shows error for the below code.
Adapter adapter = new Adapter(list,this);
It's because of this
does not reference MainActivity
inside onDataChange()
callback, it refers to the ValueEventListener