为什么项目 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);

是因为thisonDataChange()回调里面没有引用MainActivity,而是引用了ValueEventListener