Nitzan Daloomy
Nitzan Daloomy

Reputation: 306

RecycleViewAdapter gets null exception while loading it's items (RecycleView in a Fragment)

In my app I have an activity (main activity), that has in it a ViewPager, that shows Fragments. Right now I have a Fragment that has in it a RecyclerView. This RecyclerView supposed to show a list of 'Goal' objects. every time I run the app it crushes, says it has a null issue, and I thought it is probbably because of the order things were written.

I've tried then changing the order, searching on the internet for what else could the issue be, with no success.

the error log:

2019-06-26 18:51:10.544 15296-15296/com.example.performancemeasurement E/RecyclerView: No adapter attached; skipping layout
2019-06-26 18:52:23.369 15296-15349/com.example.performancemeasurement E/zygote64: Dex checksum does not match for dex: /data/data/com.example.performancemeasurement/files/instant-run/dex-temp/reload0x0000.dex.Expected: 3346174271, actual: 1626468260
2019-06-26 18:52:24.380 15296-15296/com.example.performancemeasurement E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.performancemeasurement, PID: 15296
    java.lang.NullPointerException: Attempt to invoke virtual method 'void com.github.abdularis.civ.CircleImageView.setImageResource(int)' on a null object reference
        at com.example.performancemeasurement.RecyclerViewAdapter.onBindViewHolder(RecyclerViewAdapter.java:36)
        at com.example.performancemeasurement.RecyclerViewAdapter.onBindViewHolder(RecyclerViewAdapter.java:17)
        at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6781)
        at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6823)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5752)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6019)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5854)
        at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2230)
        at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1557)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:612)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3924)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3641)
        at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4194)
        at android.view.View.layout(View.java:19654)
        at android.view.ViewGroup.layout(ViewGroup.java:6127)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:19654)
        at android.view.ViewGroup.layout(ViewGroup.java:6127)
        at androidx.viewpager.widget.ViewPager.onLayout(ViewPager.java:1775)
        at android.view.View.layout(View.java:19654)
        at android.view.ViewGroup.layout(ViewGroup.java:6127)
        at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1081)
        at android.view.View.layout(View.java:19654)
        at android.view.ViewGroup.layout(ViewGroup.java:6127)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:19654)
        at android.view.ViewGroup.layout(ViewGroup.java:6127)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
        at android.view.View.layout(View.java:19654)
        at android.view.ViewGroup.layout(ViewGroup.java:6127)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:19654)
        at android.view.ViewGroup.layout(ViewGroup.java:6127)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
        at android.view.View.layout(View.java:19654)
        at android.view.ViewGroup.layout(ViewGroup.java:6127)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at com.android.internal.policy.DecorView.onLayout(DecorView.java:782)
        at android.view.View.layout(View.java:19654)
        at android.view.ViewGroup.layout(ViewGroup.java:6127)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2584)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2293)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1451)
2019-06-26 18:52:24.380 15296-15296/com.example.performancemeasurement E/AndroidRuntime:     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7204)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:979)
        at android.view.Choreographer.doCallbacks(Choreographer.java:791)
        at android.view.Choreographer.doFrame(Choreographer.java:726)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:965)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6710)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:770)

fragment_active_goals.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ActiveGoals">

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

</FrameLayout>

goals_list_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/goalCardParent"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardCornerRadius="0dp"
    android:clickable="true"
    android:focusable="true"
    android:background="@color/cardview_light_background">
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.github.abdularis.civ.CircleImageView
            android:id="@+id/goalImage"
            android:layout_width="150dp"
            android:layout_height="0dp"
            app:layout_constraintDimensionRatio="1:1"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintVertical_bias="0.5"
            android:src="@drawable/active_brain_drawing"/>

        <TextView
            android:id="@+id/goalName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toEndOf="@id/goalImage"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:autoSizeTextType="uniform"
            android:padding="15dp"
            android:text="@string/active_goal_name_sample"/>

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.cardview.widget.CardView>

ActiveGoals.java:

public class ActiveGoals extends Fragment {

    private ArrayList<Goal> goals = new ArrayList<>();
    private RecyclerView recyclerView;

    public ActiveGoals() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.fragment_active_goals, container, false);
        recyclerView = v.findViewById(R.id.activeGoalsRecyclerView);
        initGoals();
        return v;
    }

    private void initGoals(){
        goals.add(new Goal("A", "active", "", null));
        goals.add(new Goal("B", "bronze", "", null));
        goals.add(new Goal("C", "silver", "", null));
        goals.add(new Goal("D", "gold", "", null));
        goals.add(new Goal("E", "active", "", null));
        goals.add(new Goal("F", "bronze", "", null));
        goals.add(new Goal("G", "silver", "", null));
        goals.add(new Goal("H", "gold", "", null));
        initRecyclerView();
    }

    private void initRecyclerView(){
        RecyclerViewAdapter adapter = new RecyclerViewAdapter(goals, this.getContext());
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    }

}

Goal.java:

public class Goal {
    private String name, status, description;
    private Integer imageId;
    private ArrayList<Goal> subGoals;

    public Goal(String name, String status, String description, ArrayList<Goal> subGoals) {
        this.name = name;
        this.status = status;
        this.description = description;
        this.subGoals = subGoals;

        switch (status){
            case "active":
                imageId = R.drawable.active_brain_drawing;
                break;
            case "bronze":
                imageId = R.drawable.bronze_medal;
                break;
            case "silver":
                imageId = R.drawable.silver_medal;
                break;
            case "gold":
                imageId = R.drawable.golden_medal;
                break;
            default:
                imageId = R.drawable.active_brain_drawing;
                break;
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
        switch (status){
            case "active":
                imageId = R.drawable.active_brain_drawing;
                break;
            case "bronze":
                imageId = R.drawable.bronze_medal;
                break;
            case "silver":
                imageId = R.drawable.silver_medal;
                break;
            case "gold":
                imageId = R.drawable.golden_medal;
                break;
            default:
                imageId = R.drawable.active_brain_drawing;
                break;
        }
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public ArrayList<Goal> getSubGoals() {
        return subGoals;
    }

    public void setImageId(Integer imageId) {
        this.imageId = imageId;
    }

    public Integer getImageId() {
        return imageId;
    }
}

RecyclerViewAdapter.java:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {

    private ArrayList<Goal> goals;
    private Context mContext;

    RecyclerViewAdapter(ArrayList<Goal> goals, Context mContext) {
        this.goals = goals;
        this.mContext = mContext;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.goals_list_item, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        holder.goalImage.setImageResource(goals.get(position).getImageId());

        holder.goalName.setText(goals.get(position).getName());

        holder.goalCardParent.setOnClickListener(view -> {

        });
    }

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

    class MyViewHolder extends RecyclerView.ViewHolder{

        private CardView goalCardParent;
        private CircleImageView goalImage;
        private TextView goalName;

        MyViewHolder(@NonNull View itemView) {
            super(itemView);
            goalCardParent = itemView.findViewById(R.id.goalCardParent);
            goalImage = itemView.findViewById(R.id.goalImage);
            goalName = itemView.findViewById(R.id.goalName);

        }
    }
}

Where is the problem and how can I fix it?

EDIT

Found where's the problem - the goalImage, goalName and goalCardParent under the holder in the onBindViewHolder method (in the RecyclerViewAdapter class) are all null, while the holder is not. What's the cause and how can I fix it?

thanks in advance (:

Upvotes: 1

Views: 2152

Answers (2)

Nitzan Daloomy
Nitzan Daloomy

Reputation: 306

Just figured it out! the problem was in the goal_list_item.xml (v26)... the ids of the objects were somehow different and the code could'nt find the right objects by their ids. sorry for bothering,my bad XD thanks everyone for helping me!

Upvotes: 1

Dr BigKitkat
Dr BigKitkat

Reputation: 423

I know this is a custom view, but if it extends a normal ImageView, you should instead try this because you are using a drawable ID

holder.goalImage.setImageDrawable(mContext.getDrawable(goals.get(position).getImageId()));

Upvotes: 0

Related Questions