问题描述
我遵循 Jared Burrows 的方法从这里的帖子:How to create interface between Fragment and adapter? 不幸的是,我在 line interfacePostAdapter.textMessage(username); 处获得了 NPE;我知道问题出在接口初始化上,但不幸的是我无法从所有类似的帖子中找到解决方案。
我的适配器
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();
}
});
}
}
解决方法
您需要跟踪您的变量并确保它已正确初始化。这样做之后,我得出结论,您实际上并没有在 PostDataAdapter.InterfacePostAdapter interfacePostAdapter;
的任何地方为 LoggedInFragment
赋值。我确实看到您的片段实现了上述接口,因此在这种情况下,您实际上根本不需要变量,只需将该行更改为:
postDataAdapter = new PostDataAdapter(postDataViewModel.getPostData().getValue(),interfacePostAdapter);
为此:
postDataAdapter = new PostDataAdapter(postDataViewModel.getPostData().getValue(),this);
说明:
您的变量未在任何地方初始化,因此您基本上是将 null 传递给您的适配器。有几种方法可以传递接口,但您以一种糟糕的方式混合了其中的两种方法 - 当类实现该接口时,您可以使用 this
传递当前实例,或者您可以使用变量但是适当的初始化。