0

I keep getting the error "E/RecyclerView: No adapter attached; skipping layout" when the RecyclerView list is shown. I'm getting data correctly from API but I got "void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference"

I know this question has been asked a lot before but I checked most of the questions and none has worked for me.

This is my fragment:

public class HomeFragment extends Fragment {
    private View view;
    private RecyclerView recyclerView;
    private ArrayList<Result> arrayList;
    private SwipeRefreshLayout refreshLayout;
    private PostAdapter postAdapter;
    private MaterialToolbar toolbar;
    private SharedPreferences userPref;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view =  inflater.inflate(R.layout.layout_home,container,false);
        return view;

    }
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        init();
    }
    private void init() {

        userPref = getContext().getApplicationContext().getSharedPreferences("user", Context.MODE_PRIVATE);
        recyclerView = (RecyclerView)view.findViewById(R.id.recyclerHome);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        refreshLayout = (SwipeRefreshLayout)view.findViewById(R.id.swipeHome);
        toolbar =(MaterialToolbar) view.findViewById(R.id.toolbarHome);
        ((HomeActivity)getContext()).setSupportActionBar(toolbar);
        getResults();

        refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                getResults();
            }
        });
    }

    private void getResults() {//Working Fine}
        
} 

My adapter:

public class PostAdapter extends RecyclerView.Adapter<PostAdapter.PostsHolder>{
    private ArrayList<Result> list;
    private Context context;

       public PostAdapter(Context context, ArrayList<Result> list) {
            this.list = new ArrayList<Result>(list);
            this.context = context;
    }

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

    @Override
    public void onBindViewHolder(@NonNull PostsHolder holder, int position) {
        Result result = list.get(position);
        holder.imgPostDate.setText(result.getDate());
    }

    @Override
    public int getItemCount() {
        return list.size();
    }
   public static class PostsHolder extends RecyclerView.ViewHolder{
        private TextView imgPostProfile,imgPostName,imgPostDate;
        private ImageButton btnPostOption;

        public PostsHolder(@NonNull View itemView) {
            super(itemView);
            imgPostProfile =(TextView) itemView.findViewById(R.id.imgPostProfile);
            imgPostName = (TextView)itemView.findViewById(R.id.imgPostName);
            imgPostDate =(TextView) itemView.findViewById(R.id.imgPostDate);
            btnPostOption =(ImageButton) itemView.findViewById(R.id.btnPostOption);
        }
    }
}

I modified my code according to the answers I found to similar questions but none of them worked.

layout_home

<?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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.MaterialToolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/toolbarHome"
        android:elevation="1dp"
        android:theme="@style/Theme.MaCoSISBottomAppBar"
        app:title=""
        tools:targetApi="lollipop">
        <!--    <ImageView-->
        <!--        android:layout_width="100dp"-->
        <!--        android:layout_height="40dp"-->
        <!--        android:src="@drawable/logo_dark"/>-->
    </com.google.android.material.appbar.MaterialToolbar>

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:layout_width="match_parent"
        android:id="@+id/swipeHome"
        android:layout_height="match_parent">

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

        </androidx.recyclerview.widget.RecyclerView>

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

</LinearLayout>

layout_post

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:clickable="true"
    android:focusable="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:padding="10dp">

            <TextView
                android:id="@+id/imgPostProfile"
                android:layout_width="60sp"
                android:layout_height="60sp"
                android:background="@drawable/shape_circle"
                android:text="MC"
                android:gravity="center"
                android:textColor="@color/colorWhite"
                android:textSize="14sp" />

            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:paddingLeft="6dp"
                android:orientation="vertical">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/imgPostName"
                    android:text="BBAD1252 Social Harmony and Business Skills Development"
                    android:textColor="@color/colorBlack"
                    android:textSize="14sp" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/imgPostDate"
                    android:text="12 Novermber 2020"
                    android:textColor="@color/colorLightGrey"
                    android:textSize="12dp" />
            </LinearLayout>
            <ImageButton
                android:id="@+id/btnPostOption"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="8dp"
                android:background="@android:color/transparent"
                android:layout_gravity="center_vertical"
                android:src="@drawable/ic_baseline_more_vert_24"/>
        </LinearLayout>
        <View
            android:layout_width="match_parent"
            android:layout_height="1px"
            android:background="@color/colorLightGrey"
            />
    </LinearLayout>

</androidx.cardview.widget.CardView>
  • The log indicates that you forgot to attach the adapter to the `RecyclerView`. Did you forget to call `RecyclerView#setAdapter`? – Sơn Phan Nov 11 '20 at 09:34
  • recyclerView.setAdapter(postAdapter); is called in getResults() methods – Achchuthan Yogarajah Nov 11 '20 at 09:46
  • `holder.imgPostDate.setText(result.getDate())` is the line that caused the error. Seems like `holder.imgPostDate` was null. Can you attach the xml of `R.layout.layout_home`? – Sơn Phan Nov 11 '20 at 09:48

4 Answers4

1

In onCreateViewHolder you inflated the wrong xml. It should've been R.layout.layout_post

@NonNull
@Override
public PostsHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_post, parent, false);
    return new PostsHolder(view);
}
Sơn Phan
  • 821
  • 4
  • 10
1

To prevent from error E/RecyclerView: No adapter attached; skipping layout, you should call recyclerView.setAdapter(adapter); inside your init(); method.

Then after you have your data you should notify the adapter in order to display your data by calling adapter.notifyDataSetChanged(); or using any other notify methods. Check this answer for other notify methods.

Changer
  • 316
  • 2
  • 9
0

If your getResults() is where you're calling your recyclerview.setAdapter(), you're calling setAdapter too late. You need to make sure your adapter is set during onCreateView() so that the Recyclerview isn't being skipped while drawing the layout.

Sammy T
  • 1,742
  • 1
  • 11
  • 20
0

No Adapter Attached; Skipping layout: you should setadapter in your main thread methods of fragment; then add or update data to adapter

Nullpointer at settext [at adapter]: In onCreateViewHolder you inflated the wrong xml. It should be R.layout.layout_post instead of R.layout.layout_home