简体   繁体   中英

RecyclerView Adapter return NullPointerException

I want to make double recyclerview to represent rooms on each floor. but NullPointerException occurs in floorAdapter.

public class FloorAdapter extends RecyclerView.Adapter<FloorAdapter.ViewHolder> {

    public ArrayList<FloorData> floors;
    private Context context;
    private LayoutInflater layoutInflater;

    public FloorAdapter(ArrayList<FloorData> floors, Context context) {
        this.floors = floors;
        this.context = context;
        this.layoutInflater = LayoutInflater.from(context);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = layoutInflater.inflate(R.layout.signle_floor, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.recyclerView.setAdapter(new RoomAdapter(context, floors.get(position).rooms));
        holder.recyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
        holder.recyclerView.setHasFixedSize(true);
        holder.tvFloorNum.setText(floors.get(position).floorNum);
    }

    @Override
    public int getItemCount() {
        return floors.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        RecyclerView recyclerView;
        TextView tvFloorNum;

        public ViewHolder(View itemView) {
            super(itemView);
            recyclerView = (RecyclerView) itemView.findViewById(R.id.rvFloors);
            tvFloorNum = (TextView) itemView.findViewById(R.id.tvFloorNum);
        }
    }
}
public class RoomAdapter extends RecyclerView.Adapter<RoomAdapter.CustomViewHolder> {
    private Context context;
    private ArrayList<RoomData> rooms;
    private LayoutInflater inflater;

    public RoomAdapter(Context context, ArrayList<RoomData> rooms) {
        this.context = context;
        this.rooms = rooms;
        this.inflater = LayoutInflater.from(context);
    }

    @Override
    public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view;
        view = inflater.inflate(R.layout.single_room, parent, false);
        return new CustomViewHolder(view);
    }

    @Override
    public void onBindViewHolder(CustomViewHolder holder, int position) {
        RoomData room = rooms.get(position);
        holder.tvRoomNum.setText(room.roomNum);
    }

    @Override
    public int getItemCount() {
        return rooms.size();
    }


    public class CustomViewHolder extends RecyclerView.ViewHolder {
        public TextView tvRoomNum;

        public CustomViewHolder(View itemView) {
            super(itemView);
            tvRoomNum = (TextView) itemView.findViewById(R.id.tvRoomNumber);
        }
    }
}
public class RoomActivity extends AppCompatActivity {

    private RecyclerView rvFloor;
    private FloorAdapter floorAdapter;
    private ArrayList<FloorData> floors;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_room);


        floors = prepareData();

        rvFloor = findViewById(R.id.rvFloors);

        floorAdapter = new FloorAdapter(floors, RoomActivity.this);
        LinearLayoutManager manager = new LinearLayoutManager(RoomActivity.this);
        rvFloor.setLayoutManager(manager);
        rvFloor.setAdapter(floorAdapter);

    }

    private ArrayList<FloorData> prepareData() {
        ArrayList<FloorData> floors = new ArrayList<FloorData>();

        //첫번째 subject 추가
        FloorData floor1 = new FloorData();
        floor1.floorNum = 1;
        floor1.rooms = new ArrayList<RoomData>();

        RoomData room101 = new RoomData();
        room101.roomNum = 101;

        RoomData room102 = new RoomData();
        room102.roomNum = 102;

        RoomData room103 = new RoomData();
        room103.roomNum = 103;

        floor1.rooms.add(room101);
        floor1.rooms.add(room102);
        floor1.rooms.add(room103);


        floors.add(floor1);

        FloorData floor2 = new FloorData();
        floor2.floorNum = 2;
        floor2.rooms = new ArrayList<RoomData>();

        RoomData room201 = new RoomData();
        room201.roomNum = 201;

        RoomData room202 = new RoomData();
        room202.roomNum = 202;

        RoomData room203 = new RoomData();
        room203.roomNum = 203;

        floor2.rooms.add(room201);
        floor2.rooms.add(room202);
        floor2.rooms.add(room203);


        floors.add(floor2);


        return floors;
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".tools.RewardActivity"
    android:orientation="vertical">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolBar_room"
        android:layout_width="match_parent"
        android:layout_gravity="center"
        android:layout_height="60dp"
        android:background="@color/colorPrimaryDark"
        app:title="호실 등록"
        android:theme="@style/ToolbarTheme" />


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rvFloors"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">


    <LinearLayout
        android:orientation="vertical"
        android:background="#FFFFFF"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="15dp">

        <TextView
            android:id="@+id/tvFloorNum"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:textSize="30dp"
            android:textColor="#000000" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rvRooms"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </LinearLayout>
</LinearLayout>
<LinearLayout 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_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="2dp">


        <TextView
            android:id="@+id/tvRoomNumber"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginTop="5dp"
            android:ellipsize="end"
            android:singleLine="true"
            android:background="@color/colorPrimary"
            />

    </LinearLayout>

</LinearLayout>

Logcat explain

"java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setAdapter(androidx.recyclerview.widget.RecyclerView$Adapter)' on a null object reference"

I refer to https://medium.com/@ashishkudale/android-list-inside-list-using-recyclerview-73cff2c4ea95 . It's almost the same, but I don't know why the error is happening. please help me

two things. First, in your FloorAdapter's ViewHolder's constructor, you are finding recycler view of activity instead of that of Adapter. Change your code to,

public ViewHolder(View itemView) {
            super(itemView);
            recyclerView = (RecyclerView) itemView.findViewById(R.id.rvRooms); //**This is rvFloors in your code**
            tvFloorNum = (TextView) itemView.findViewById(R.id.tvFloorNum);
        }

in FloorAdapter. This will resolve your crash.

But you will experience two more crashes here

@Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.recyclerView.setAdapter(new RoomAdapter(context, floors.get(position).rooms));
        holder.recyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
        holder.recyclerView.setHasFixedSize(true);
        holder.tvFloorNum.setText(floors.get(position).floorNum); // **Crash will be on this line**
    }

and

@Override
    public void onBindViewHolder(CustomViewHolder holder, int position) {
        RoomData room = rooms.get(position);
        holder.tvRoomNum.setText(room.roomNum);//**Crash will be on this line**
    }

These will happen because setText method takes String as argument but you are passing either Integer or int.

So change both these lines to

  1. holder.tvFloorNum.setText(String.valueOf(floors.get(position).floorNum));
  2. holder.tvRoomNum.setText(String.valueOf(room.roomNum));

Hope this answer helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM