java.lang.NullPointerException at android.support.v7.widget.RecyclerView.onMeasure-ThrowExceptions

Exception or error:

I try to use RecyclerView with RecyclerView.Adapter but here is something wrong. I post my code below:

Layout:

   <android.support.v7.widget.RecyclerView
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/topic_view"
    android:scrollbars="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

topic_tile.xml:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="@dimen/tile_height">

    <com.makeramen.RoundedImageView
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/avatar"
        android:padding="16dp"
        app:riv_corner_radius="72dp"
        android:layout_height="72dp"
        android:layout_width="72dp"
        />

    <LinearLayout
        android:id="@+id/text_layout"
        android:orientation="vertical"
        android:paddingTop="@dimen/text_padding_top_and_bottom"
        android:paddingBottom="@dimen/text_padding_top_and_bottom"
        android:paddingRight="16dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/title"
            android:textSize="@dimen/primary_font"
            android:paddingLeft="@dimen/text_padding_left"
            android:textColor="#000000"
            android:text="Title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/author"
            android:textSize="@dimen/secondary_font"
            android:paddingLeft="@dimen/text_padding_left"
            android:text="author"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </LinearLayout>
</RelativeLayout>

Here is in onCreate()

public class TitleListActivity extends ActionBarActivity {

    private RecyclerView topic_view;
    private RecyclerView.LayoutManager mLayoutManager;
    private TitlelistAdapter adapter;

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

        .....

        topic_view = (RecyclerView)findViewById(R.id.topic_view);
        adapter = new TitlelistAdapter(topicList);

        topic_view.setHasFixedSize(true);
        mLayoutManager = new LinearLayoutManager(TitleListActivity.this);
        topic_view.setLayoutManager(mLayoutManager);
        topic_view.setItemAnimator(new DefaultItemAnimator());

        topic_view.setAdapter(adapter);

the Adapter:

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

    public List<Topic> topicList;

    public static class ViewHolder extends RecyclerView.ViewHolder{

        TextView title;
        TextView author;
        RoundedImageView avatar;

        public ViewHolder(View itemView) {
            super(itemView);

            title = (TextView)itemView.findViewById(R.id.title);
            author = (TextView)itemView.findViewById(R.id.author);
            avatar = (RoundedImageView)itemView.findViewById(R.id.avatar);
        }
    }

    public TitlelistAdapter(List<Topic> topicList){
        this.topicList = topicList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {

        View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.topic_tile,viewGroup,false);
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        viewHolder.title.setText(topicList.get(i).title);
        viewHolder.author.setText(topicList.get(i).member.username);
    }

    @Override
    public long getItemId(int position) {
        return super.getItemId(position);
    }

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

Here is the exception:

java.lang.NullPointerException
        at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:1694)
        at android.view.View.measure(View.java:16497)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
        at android.view.View.measure(View.java:16497)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
        at android.view.View.measure(View.java:16497)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
        at android.support.v7.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:453)
        at android.view.View.measure(View.java:16497)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
        at android.view.View.measure(View.java:16497)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
        at android.view.View.measure(View.java:16497)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2291)
        at android.view.View.measure(View.java:16497)
        at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1912)
        at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1109)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1291)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:996)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5600)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
        at android.view.Choreographer.doCallbacks(Choreographer.java:574)
        at android.view.Choreographer.doFrame(Choreographer.java:544)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5001)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
        at dalvik.system.NativeStart.main(Native Method)

Is it something I didn’t init or something I should write more?

How to solve:

I got this error when my RecyclerView had no LayoutManager. Adding this code fixed the problem:

recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));

###

Your xml shows that you have two android namespaces which actually should give you an error because in android you are allowed to use the namespace only once. Remove the linearLayout from your main layout as it seems unnecessary. Check your custom Row layout i.e topic_tile as well for any similar errors

<android.support.v7.widget.RecyclerView 
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/topic_view"
    android:scrollbars="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

EDIT :

in onCreate()

private RecyclerView.LayoutManager mLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        .
        . 
        .
        mLayoutManager = new LinearLayoutManager(this);
        recycleView.setLayoutManager(mLayoutManager);
    }

###

If your are facing the same issue for RecycleView inside a fragment, try to use this code.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View rootView = inflater.inflate(R.layout.fragment_latest, container, false);

    // get recycler view
    mRecyclerView = (RecyclerView) rootView.findViewById(R.id.novel_item_list);

    //mRecyclerView.setHasFixedSize(true);

    // use a linear layout manager
    mLayoutManager = new LinearLayoutManager(getActivity());
    mRecyclerView.setLayoutManager(mLayoutManager);


    String[] abc = {"hi","how are you","this is recycler"};
    // specify an adapter (see also next example)
    mAdapter = new RecyclerViewAdapter(abc);
    mRecyclerView.setAdapter(mAdapter);
    return rootView;
}

###

You have to set LayoutManager for RecycleView:

Currently, android supports 3 kinds of layouts.

If you want it seems a normal ListView, use LinearLayoutManager.

If you want it seems a gridView, use GridLayoutManager.

If you want it seem staggered, use StaggeredGridLayoutManager

Constructors for 3 kinds layouts above

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());

GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 2);

StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(spanCount, StaggeredGridLayoutManager.HORIZONTAL);

Then you set LinearLayout to RecycleView ( in this case I used LinearLayoutManager

recyclerView = (RecyclerView) view.findViewById(R.id.saved_recycle_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(linearLayoutManager);

Anyway, use OttoBus Library to pass out events from the Adapter to Activity/Fragment containing the RecycleView.
Good luck !

###

For anyone trying to use a ViewPager for tabs, and inside their tabs have a RecyclerView which causes this crazy error, I suggest to postpone inflating by creating yet another Fragment for including only the RecylerView.

This xml file is one of my tabs which contain a frame layout instead a recycler .

shop_most_views_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<FrameLayout
    android:id="@+id/most_view_item_frameLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f3f3f3" />
</LinearLayout>

its java class

public class MostViews extends Fragment {
private String title;
private int page;
View convertedView;
RecyclerView grids;

public static MostViews newInstance(int page, String title) {
    MostViews fragmentFirst = new MostViews();
    Bundle args = new Bundle();
    args.putInt("someInt", page);
    args.putString("someTitle", title);
    fragmentFirst.setArguments(args);
    return fragmentFirst;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    page = getArguments().getInt("someInt", 0);
    title = getArguments().getString("someTitle");
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    convertedView = inflater.inflate(R.layout.shop_most_views_fragment, container, false);
    transitMasonaryLayoutFragmentIntoFramLayout();
    return convertedView;
}

private void transitMasonaryLayoutFragmentIntoFramLayout() {
    MasanoryLayout masanoryLayout = new MasanoryLayout();
    FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
    fragmentManager.beginTransaction()
            .add(R.id.most_view_item_frameLayout, masanoryLayout).commit();
}
}

so we have a frame layout to put our recylcer fragment into it.

shop_most_view_masanory_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v7.widget.RecyclerView
    android:id="@+id/mostViewsItem"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
</LinearLayout>

its java class

public class MasanoryLayout extends Fragment {
View convertedView;
RecyclerView grids;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    convertedView = inflater.inflate(R.layout.shop_most_view_masanory_fragment, container, false);
    grids = (RecyclerView) convertedView.findViewById(R.id.mostViewsItem);
    setLayoutManagerOnRecyclerView();
    MasonryAdapter adapter = new MasonryAdapter(initializeData());
    grids.setAdapter(adapter);
    return convertedView;
}

private void setLayoutManagerOnRecyclerView() {
    grids.setLayoutManager(new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL));
}

private List<StoreItem> initializeData() {
    List<StoreItem> storeItems = new ArrayList<>();
    storeItems.add(new StoreItem("احسان", "احسان", R.drawable.detailed_index_store));
    storeItems.add(new StoreItem("احسان", "احسان", R.drawable.clothstore));
    storeItems.add(new StoreItem("احسان", "احسان", R.drawable.detailed_index_store));
    storeItems.add(new StoreItem("احسان", "احسان", R.drawable.clothstore));
    storeItems.add(new StoreItem("احسان", "احسان", R.drawable.detailed_index_store));
    storeItems.add(new StoreItem("احسان", "احسان", R.drawable.detailed_index_store));
    storeItems.add(new StoreItem("احسان", "احسان", R.drawable.clothstore));

    return storeItems;
}
}

as you see your FragmentPagerAdapter would call MostViews to be inflated and MostViews itself would call MasanoryLayout to be inflated. so we escaped FragmentPagerAdapter context 😉

Leave a Reply

Your email address will not be published. Required fields are marked *