【问题标题】:Null Pointer Exception by Invoke Interface between RecyclerView Adapter and Fragment调用 RecyclerView Adapter 和 Fragment 之间的接口导致空指针异常
【发布时间】:2021-07-01 07:58:24
【问题描述】:

我在这里的帖子中遵循 Jared Burrows 的方法:How to create interface between Fragment and adapter? 不幸的是,我在 interfacePostAdapter.textMessage(username);我知道问题在于接口初始化,但不幸的是我无法从所有类似的帖子中找到解决方案。

我的适配器

public class PostDataAdapter extends RecyclerView.Adapter<PostDataAdapter.ViewHolder> {
    private ArrayList<PostData> arrayList;
    private InterfacePostAdapter interfacePostAdapter;

    public PostDataAdapter(ArrayList<PostData> arrayList, InterfacePostAdapter interfacePostAdapter) {
        this.arrayList = arrayList;
        this.interfacePostAdapter = interfacePostAdapter;
    }


    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_postdata_recyclerview,parent, false);
        ViewHolder viewHolder = new ViewHolder(view,interfacePostAdapter);
        return viewHolder;
    }

    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.name.setText(arrayList.get(position).getName());
    }

    public int getItemCount() {
        return  arrayList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder{
        TextView name;
        ImageView userImg;
        InterfacePostAdapter interfacePostAdapter;
        public ViewHolder(View itemView, InterfacePostAdapter interfacePostAdapter) {
            super(itemView);
            name = itemView.findViewById(R.id.textView_name);
            userImg = itemView.findViewById(R.id.imgView_userIcon);
            this.interfacePostAdapter = interfacePostAdapter;

            userImg.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = getBindingAdapterPosition();
                    String username = arrayList.get(position).getName();
                    interfacePostAdapter.textMessage(username);  // here is NullPointerException
                }
            });
        }
    }

    public interface InterfacePostAdapter {
        void textMessage (String username);
    }
}

我的片段

public class LoggedInFragment extends Fragment implements PostDataAdapter.InterfacePostAdapter {

    private FragmentLoggedinBinding binding;
    private PostDataAdapter postDataAdapter;
    private PostDataViewModel postDataViewModel;
    private RecyclerView recyclerView;
    PostDataAdapter.InterfacePostAdapter interfacePostAdapter;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_loggedin, container, false);
        View view = binding.getRoot();
        recyclerView = binding.recyclerView;
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        postDataAdapter = new PostDataAdapter(postDataViewModel.getPostData().getValue(), interfacePostAdapter);
        recyclerView.setAdapter(postDataAdapter);
        return view;
    }

    @Override
    public void textMessage(String username) {
        Toast.makeText(getContext(),username, Toast.LENGTH_SHORT).show();
    }

    //This part should be not relevant to the interface issue
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        postDataViewModel = new ViewModelProvider(this).get(PostDataViewModel.class);
        postDataViewModel.initPostData();
        postDataViewModel.getPostData().observe(this, new Observer<ArrayList<PostData>>() {
            @Override
            public void onChanged(ArrayList<PostData> arrayList) {
                postDataAdapter.notifyDataSetChanged();
            }
        });
    }
}

【问题讨论】:

标签: android android-recyclerview interface nullpointerexception adapter


【解决方案1】:

您需要跟踪您的变量并确保它已正确初始化。这样做之后,我得出的结论是,您实际上并没有在任何地方的LoggedInFragment 中给PostDataAdapter.InterfacePostAdapter interfacePostAdapter; 赋值。我确实看到您的片段实现了上述接口,所以在这种情况下,您实际上 根本不需要 变量,只需更改该行:

postDataAdapter = new PostDataAdapter(postDataViewModel.getPostData().getValue(), interfacePostAdapter);

到这里:

postDataAdapter = new PostDataAdapter(postDataViewModel.getPostData().getValue(), this);

说明:

您的变量未在任何地方初始化,因此您基本上将 null 传递给您的适配器。有几种方法可以传递一个接口,但你以一种糟糕的方式混合了其中的两种——当类实现该接口时,你可以使用this 传递当前实例,或者你可以使用你的变量,但使用适当的初始化。

【讨论】:

  • 我花了一天时间试图弄清楚。感谢 Vucko 的解决方案和很好的解释!不幸的是,我不能支持你的答案,因为我没有足够的评价
  • 别担心,伙计!很高兴有帮助。如果您不介意,您可以接受答案,这将关闭问题,以便人们知道它已解决:-)
猜你喜欢
  • 1970-01-01
  • 2017-07-24
  • 2021-03-27
  • 1970-01-01
  • 1970-01-01
  • 2014-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多