xamarinandroid-recyclerviewxamarin.androidpagerslidingtabstrip

Xamarin - RecyclerView with PagerSlidingTabStrip - System.NullReferenceException in SetLayoutManager()


I try to use a RecyclerView in a SlideMenu.

I use this example for my SlideMenu : https://github.com/jamesmontemagno/PagerSlidingTabStrip-for-Xamarin.Android

And now, I add RecyclerView with SlideMenu. I need two menu : "menu" and "product", so I use two xml file for my fragment : menu.xml for "menu" and menu_recyclerView.xml for "product".

This is my code :

Main.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"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:fitsSystemWindows="true" >
  <include
    android:id="@+id/top_menu"
    layout="@layout/top_menu"/>
  <com.refractored.PagerSlidingTabStrip
      android:id="@+id/tabs"
      android:layout_width="match_parent"
      android:layout_height="?attr/actionBarSize"
      app:pstsShouldExpand="true"
      android:background="@color/Blue"
      app:pstsDividerWidth="1dp"
      app:pstsDividerPadding="12dp"
      app:pstsDividerColor="#50FFFFFF"
      android:textColor="@color/Green"
      app:pstsTextColorSelected="@color/White"
      app:pstsIndicatorColor="@color/Red"
      app:pstsUnderlineColor="@color/White"/>
  <android.support.v4.view.ViewPager
      android:id="@+id/pager"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"/>
</LinearLayout>

menu_recyclerView.xml

<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
  <android.support.v7.widget.CardView
      android:id="@+id/menu_recyclerView"
      android:layout_width="match_parent"
      android:layout_height="match_parent">
      <android.support.v7.widget.RecyclerView
          android:id="@+id/recyclerView"
          android:layout_width="match_parent"
          android:layout_height="match_parent" />
  </android.support.v7.widget.CardView>
</LinearLayout>

row_recyclerView is a pattern for my items

row_recyclerView.xml

<?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"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="1dp">
  <LinearLayout
      android:layout_width="0dp"
      android:layout_height="match_parent"
      android:paddingRight="15dp"
      android:paddingLeft="15dp"
      android:orientation="vertical">
    <refractored.controls.CircleImageView
        android:id="@+id/imageView"
        app:civ_border_width="2dp"
        app:civ_border_color="#000000"/>
  </LinearLayout>
  <LinearLayout
      android:layout_width="0dp"
      android:layout_height="match_parent"
      android:layout_weight="88"
      android:orientation="vertical"
      android:paddingRight="10dp"
      android:paddingLeft="10dp"
      android:paddingTop="7dp"
      android:paddingBottom="7dp">
    <TextView
        android:text="Name"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/txtName"
        android:textColor="#000"
        android:gravity="center_vertical"
        android:padding="2dp"
        android:textSize="18sp" />
    <TextView
        android:text="Brand"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/txtBrand"
        android:textColor="#000"
        android:gravity="center_vertical"
        android:padding="2dp"
        android:textSize="14sp"
        android:singleLine="true" />
    <TextView
        android:text="Description"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/txtDescription"
        android:textColor="#000"
        android:gravity="center_vertical"
        android:padding="2dp"
        android:textSize="16sp" />
  </LinearLayout>
</LinearLayout>

-

public class MainActivity : BaseActivity
{
    protected override int LayoutResource
    {
        get
        {
            return Resource.Layout.Main;
        }
    }

    private Android.Widget.Toolbar _topMenu;
    private Adapter _adapter;
    private ViewPager _pager;
    private PagerSlidingTabStrip _tabs;

    private RecyclerView _recyclerView;
    private LayoutManager _layoutManager;

    public string _tag = "MainActivity";

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        _recyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);
        _layoutManager = new LayoutManager(this, _recyclerView);

        _layoutManager.addItem("one", "two", "three");
        _layoutManager.addItem("one", "two", "three");

        _layoutManager.createLayoutManager();

        _adapter = new Adapter(SupportFragmentManager);
        _pager = FindViewById<ViewPager>(Resource.Id.pager);
        _tabs = FindViewById<PagerSlidingTabStrip>(Resource.Id.tabs);

        _pager.Adapter = _adapter;
        _tabs.SetViewPager(_pager);
        _topMenu = FindViewById<Android.Widget.Toolbar>(Resource.Id.top_menu);
        SetActionBar(_topMenu);
    }

-

class LayoutManager
{
    public RecyclerView _mRecyclerView;
    public RecyclerView.LayoutManager _mLayoutManager;
    public RecyclerView.Adapter _mAdapter;
    public ItemList<Item> _mItems;
    public Activity _main;
    public LayoutManager(Activity main, RecyclerView recyclerView)
    {
        _main = main;
        _mRecyclerView = recyclerView;
        _mItems = new ItemList<Item>();
    }
    public void createLayoutManager()
    {
        _mLayoutManager = new LinearLayoutManager(_main);
        _mRecyclerView.SetLayoutManager(_mLayoutManager);
        _mAdapter = new RecyclerAdapter(_mItems, _mRecyclerView);
        _mItems.Adapter = _mAdapter;
        _mRecyclerView.SetAdapter(_mAdapter);
    }
    public void addItem(string name, string brand, string description)
    {
        _mItems.Add(new Item()
        {
            Img = Resource.Drawable.Icon,
            Name = name,
            Brand = brand,
            Desciption = description
        });
    }
}

And in this line (in my LayoutManager.cs):

_mRecyclerView.SetLayoutManager(_mLayoutManager);

I have This error :

System.NullReferenceException: Object reference not set to an instance of an object.

I do not understand what is the value of the probleme ? I forget any thing ? I am completely lost ? Please.. help !

Thanks you, Romain


Solution

  • According to your code: public class MainActivity : BaseActivity and

    protected override int LayoutResource
    {
        get
        {
            return Resource.Layout.Main;
        }
    }
    

    I guess that your BaseActivity is the same as BaseActivity.cs of PagerSlidingTabStrip sample.

    Then you actually here set your Main.xml as the content view of your MainActivity, and in this Main.xml, there is no RecyclerView with the id recyclerView, it is in your menu_recyclerView.xml. Although you can find the id recyclerView when you coding, but it is not present on the content view.

    So in your MainActivity, when you try to find it using _recyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);, this _recyclerView here should be null when you run your code. Then of course when you call _layoutManager = new LayoutManager(this, _recyclerView);, you pass a null to this LayoutManager. You can insert a break point on this line to check if it is a null:

    _recyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);
    

    To solve your issue, I think you may need to redesign your layout or your frame.