RecyclerView 上的空指针
Posted
技术标签:
【中文标题】RecyclerView 上的空指针【英文标题】:Null Pointer on RecyclerView 【发布时间】:2020-05-25 22:52:05 【问题描述】:我的 recyclersetup 方法中的以下语句出现空指针异常。
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
这是由于下面的语句没有在前面的语句中设置指向recyclerView的指针
recyclerView = getView().findViewById(R.id.check_in_recent_row);
我无法确定为什么我没有获得通过此语句建立的 recyclerView 指针。数据的 ID 是正确的。我错过了什么?
这是整个片段代码
CheckInRecentList.java
package com.example.checkingin;
import android.content.Context;
import android.net.Uri;
import android.nfc.Tag;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelProvider.Factory;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import java.util.List;
import static androidx.constraintlayout.widget.Constraints.TAG;
/**
* A simple @link Fragment subclass.
* Activities that contain this fragment must implement the
* @link CheckInRecentList.OnFragmentInteractionListener interface
* to handle interaction events.
* Use the @link CheckInRecentList#newInstance factory method to
* create an instance of this fragment.
*/
public class CheckInRecentList extends Fragment
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private RecyclerView recyclerView;
private RecyclerView.Adapter checkInListAdapter;
//private RecyclerView.LayoutManager layoutManager;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private MainViewModel mViewModel;
private CheckInListAdapter adapter;
private MainViewModelProviderFactory viewModelFactory;
private TextView checkInLastDateTime;
private TextView checkInTitle;
private TextView checkInDestinationName;
private TextView checkInComments;
private OnFragmentInteractionListener mListener;
public CheckInRecentList()
// Required empty public constructor
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment CheckInRecentList.
*/
// TODO: Rename and change types and number of parameters
public static CheckInRecentList newInstance(String param1, String param2)
CheckInRecentList fragment = new CheckInRecentList();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate: On Create");
if (getArguments() != null)
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
// These were originally set up from the recycler view add to the fragment
// recyclerView = findViewById(R.id.check_in_recent_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
//recyclerView.setHasFixedSize(true);
/*
// use a linear layout manager
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
*/
// specify an adapter (see also next example)
//checkInListAdapter = new CheckInListAdapter();
// recyclerView.setAdapter(checkInListAdapter);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
mViewModel = new ViewModelProvider(this, viewModelFactory).get(MainViewModel.class);
Log.i(TAG, "onCreateView: On Create View");
// Inflate the layout for this fragment
return inflater.inflate(R.layout.recycler_view_item, container, false);
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri)
Log.i(TAG, "onButtonPressed: ");
if (mListener != null)
mListener.onFragmentInteraction(uri);
@Override
public void onAttach(Context context)
super.onAttach(context);
Log.i(TAG, "onAttach: OnAttach");
viewModelFactory = new MainViewModelProviderFactory(context.getApplicationContext());
mViewModel = new ViewModelProvider(this, viewModelFactory).get(MainViewModel.class);
if (context instanceof OnFragmentInteractionListener)
mListener = (OnFragmentInteractionListener) context;
else
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
Log.i(TAG,"OnAttach completed");
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
Log.i(TAG, "onActivityCreated: On Activity Created");
mViewModel = new ViewModelProvider(this, viewModelFactory).get(MainViewModel.class);
checkInLastDateTime = getView().findViewById(R.id.checkInLastDateTime);
checkInTitle = getView().findViewById(R.id.checkInTitle);
checkInDestinationName = getView().findViewById(R.id.checkInDestinationName);
checkInComments = getView().findViewById(R.id.checkInComments);
recyclerSetup();
Log.i(TAG,"OnActivityCreated: Recycler SetUp");
//listenerSetup();
//Log.i(TAG, "onActivityCreated: Listener SetUp");
observerSetup();
Log.i(TAG, "onActivityCreated: Observer SetUp");
@Override
public void onDetach()
super.onDetach();
Log.i(TAG, "onDetach: ");
mListener = null;
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
private void clearFields()
checkInLastDateTime.setText("");
checkInDestinationName.setText("");
checkInTitle.setText("");
checkInComments.setText("");
private void listenerSetup()
ImageButton editCheckInButton = getView().findViewById(R.id.checkInEditButton);
ImageButton resendCheckInButton = getView().findViewById(R.id.checkInResendButton);
mViewModel = new ViewModelProvider(this, viewModelFactory).get(MainViewModel.class);
Log.i(TAG, "listenerSetup: ");
editCheckInButton.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
//put in edit check in logic
);
resendCheckInButton.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
//put in resend logic
);
private void observerSetup()
Log.i(TAG, "observerSetup:");
if(mViewModel.getAllCheckIn() != null)
mViewModel.getAllCheckIn().observe(getViewLifecycleOwner(), new Observer<List<CheckInTable>>()
@Override
public void onChanged(@Nullable final List<CheckInTable> allCheckIn)
adapter.setCheckInList(allCheckIn);
);
mViewModel.getAllCheckIn().observe(getViewLifecycleOwner(), new Observer<List<CheckInTable>>()
@Override
public void onChanged(@Nullable final List<CheckInTable> allCheckIn)
if (allCheckIn.size() > 0)
Log.i(TAG, "onChanged: all check in size greater than zero");
checkInLastDateTime.setText(allCheckIn.get(0).getCheckInLastDateTime());
Log.i(TAG, "onChanged: running again");
checkInDestinationName.setText(allCheckIn.get(0).getCheckInDestinationName());
checkInTitle.setText(allCheckIn.get(0).getCheckInTitle());
checkInComments.setText(allCheckIn.get(0).getCheckInComments());
else
checkInLastDateTime.setText("None Found");
);
private void recyclerSetup()
Log.i(TAG, "recyclerSetup: ");
adapter = new CheckInListAdapter(R.layout.fragment_check_in_recent_list);
RecyclerView recyclerView = getView().findViewById(R.id.check_in_recent_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
//recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
以下是片段的xml文件 fragment_check_in_recent_list.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
tools:context=".CheckInRecentList">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/check_in_recent_recycler_view"
android:layout_
android:layout_
tools:listitem="@layout/recycler_view_item"/>
</FrameLayout>
和recycler_view_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:padding="8dp"
android:layout_
android:layout_>
<TableLayout
android:id="@+id/check_in_recent_row"
android:layout_
android:layout_
android:layout_gravity="center"
android:padding="30dp">
<TableRow
android:layout_
android:layout_>
<TextView
android:id="@+id/checkInLastDateTime"
android:layout_
android:layout_
android:text="TextView"/>
<TextView
android:id="@+id/checkInTitle"
android:layout_
android:layout_
android:text="TextView" />
<TextView
android:id="@+id/checkInDestinationName"
android:layout_
android:layout_
android:text="TextView" />
<ImageButton
android:id="@+id/checkInEditButton"
android:layout_
android:layout_
android:src="@android:drawable/ic_menu_edit"
android:tooltipText="Edit Check In" />
<ImageButton
android:id="@+id/checkInResendButton"
android:layout_
android:layout_
android:src="@android:drawable/ic_menu_share"
android:tooltipText="Resend Check In" />
</TableRow>
<TableRow
android:layout_
android:layout_>
<TextView
android:id="@+id/checkInComments"
android:layout_
android:layout_
android:text="TextView" />
</TableRow>
</TableLayout>
</LinearLayout>
CheckInListAdapter
package com.example.checkingin;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.app.Activity;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import static androidx.constraintlayout.widget.Constraints.TAG;
public class CheckInListAdapter extends RecyclerView.Adapter<CheckInListAdapter.ViewHolder>
private int checkInListLayout;
private List<CheckInTable> checkInList;
public CheckInListAdapter(int layoutId)
checkInListLayout = layoutId;
public void setCheckInList(List<CheckInTable> allCheckIn)
checkInList = allCheckIn;
notifyDataSetChanged();
@Override
public int getItemCount()
return checkInList == null ? 0 : checkInList.size();
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
Log.i(TAG, "onCreateViewHolder: ");
View view = LayoutInflater.from(
parent.getContext()).inflate(checkInListLayout, parent, false);
ViewHolder checkInListViewHolder = new ViewHolder(view);
return checkInListViewHolder;
@Override
public void onBindViewHolder(final ViewHolder holder, final int listPosition)
TextView checkInLastDateTime = holder.checkInLastDateTime;
TextView checkInTitle = holder.checkInTitle;
TextView checkInDestinationName = holder.checkInDestinationName;
TextView checkInComments = holder.checkInComments;
ImageView checkInEditButton = holder.checkInEditButton;
ImageView checkInResendButton = holder.checkInResendButton;
Log.i(TAG, "onBindViewHolder: ");
checkInLastDateTime.setText(checkInList.get(listPosition).getCheckInLastDateTime());
checkInTitle.setText(checkInList.get(listPosition).getCheckInTitle());
checkInDestinationName.setText(checkInList.get(listPosition).getCheckInDestinationName());
checkInComments.setText(checkInList.get(listPosition).getCheckInComments());
holder.checkInEditButton.setImageResource(R.drawable.ic_menu_edit);
holder.checkInResendButton.setImageResource(R.drawable.ic_menu_share);
ImageButton editCheckInButton = checkInEditButton.findViewById(R.id.checkInEditButton);
ImageButton resendCheckInButton = checkInResendButton.findViewById(R.id.checkInResendButton);
editCheckInButton.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
//put in edit check in logic
);
resendCheckInButton.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
//put in resend logic
);
static class ViewHolder extends RecyclerView.ViewHolder
TextView checkInLastDateTime;
TextView checkInTitle;
TextView checkInDestinationName;
TextView checkInComments;
ImageView checkInEditButton;
ImageView checkInResendButton;
ViewHolder(View itemView)
super(itemView);
Log.i(TAG, "ViewHolder: ");
checkInLastDateTime = itemView.findViewById(R.id.checkInLastDateTime);
checkInTitle = itemView.findViewById(R.id.checkInTitle);
checkInDestinationName = itemView.findViewById(R.id.checkInDestinationName);
checkInComments = itemView.findViewById(R.id.checkInComments);
checkInEditButton = itemView.findViewById(R.id.checkInEditButton);
checkInResendButton = itemView.findViewById(R.id.checkInResendButton);
itemView.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
);
【问题讨论】:
这能回答你的问题吗? What is a NullPointerException, and how do I fix it? 【参考方案1】:您的 RecyclerView
的 ID 是 check_in_recent_recycler_view
。您的findViewById
呼叫正在使用check_in_recent_row
。这些需要匹配。
【讨论】:
我试过了,但不幸的是遇到了同样的问题,我把这两行改成了。还添加了上面的适配器代码。适配器 = 新 CheckInListAdapter(R.layout.fragment_check_in_recent_list); RecyclerView recyclerView = getView().findViewById(R.id.check_in_recent_recycler_view);issue. 我找到了。还需要更改 OnCreateView 中的布局 ID。感谢您的帮助。以上是关于RecyclerView 上的空指针的主要内容,如果未能解决你的问题,请参考以下文章
SwipeRefreshLayout和RecyclerView类
尝试在 recyclerview kotlin 上的空对象引用上调用虚拟方法 'void android.widget.TextView.setText(java.lang.CharSequence)
Jetpack compose 中的 [NestedScrollView + RecyclerView] 或 [Nested RecyclerView (Recycler inside another