batrand
batrand

Reputation: 146

MvvmCross + Xamarin.Android: how to setup MvxRecyclerView inside CardView inside ViewPager?

My parent activity contains a ViewPager that hosts 3 fragments.

MainView:

<CoordinatorLayout>
    <AppBarLayout/>
    <ViewPager/>
</CoordinatorLayout>

In one fragment, I have a RecyclerView that displays CardViews as items

Child fragment:

<CoordinatorLayout>
    <MvxSwipeRefreshLayout>
        <MvxRecyclerView
           local:MvxItemTemplate="@layout/child_item">
    </MvxSwipeRefreshLayout>
</CoordinatorLayout>

Inside the child fragment I want each child (a CardView) to host its own RecyclerView that 1) displays its child horizontally and 2) scrollable. But the problem is, even though I have set the layoutManager and the orientation values in XML, it does not work. It displays things vertically and does not scroll.

Child_item

<CardView>
  <MvxRecyclerView
     local:layoutManager="android.support.v7.widget.LinearLayoutManager"
     android:orientation="horizontal"
     local:MvxItemTemplate="@layout/child_child"
     android:background="@color/Red"/>

</CardView>

Child item inside the Cardview child_child.xml:

<LinearLayout android:background="@color/Grey">
    <Button>
</LinearLayout>

Currently, the main ViewPager works fine; I can swipe to change fragments. The child fragment also supports vertical scrolling; I tried adding multiple cardviews so that it has to scroll, and I can do that just fine. Inside the cardview I added a Seekbar to see if child elements were receiving touch inputs, which also worked. Only the RecyclerView inside the card is not receiving any touch inputs, or responding to the orientation = horizontal request.

How it is currently: The "XXXXX" buttons are stacked vertically. Note that there are more than 2 "XXXX" buttons. THe cardview clipped it but ot does not scroll. screenshot of current state

What is expected/what I'm trying to achieve: the buttons should be stacked horizontally and should be scrollable.

Upvotes: 0

Views: 1210

Answers (1)

batrand
batrand

Reputation: 146

There is a bug in MvxRecyclerView in MvvmCross 4.4.0 that ignores XML atrributes and simply hardcodes a default LinearLayoutManager. Further developments at GitHub issue.

For the time being, for this use case, I hard-coded an MvxRecyclerView subclass to SetLayoutManager(new LinearLayoutManager(context) { Orientation = Horizontal }); and it works.

[Register("bug.droid.components.BugFixRecyclerView")]
public sealed class BugFixRecyclerView : MvxRecyclerView
{
    public BugFixRecyclerView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
    {
    }

    public BugFixRecyclerView(Context context, IAttributeSet attrs) : this(context, attrs, 0, new MvxRecyclerAdapter())
    {
    }

    public BugFixRecyclerView(Context context, IAttributeSet attrs, int defStyle) : this(context, attrs, defStyle, new MvxRecyclerAdapter())
    {
    }

    public BugFixRecyclerView(Context context, IAttributeSet attrs, int defStyle, IMvxRecyclerAdapter adapter) : base(context, attrs, defStyle, adapter)
    {
        if (adapter == null)
            return;

        var layoutManager = new LinearLayoutManager(context) { Orientation = Horizontal };
        SetLayoutManager(layoutManager);            

        var itemTemplateId = MvxAttributeHelpers.ReadListItemTemplateId(context, attrs);
        var itemTemplateSelector = MvxRecyclerViewAttributeExtensions.BuildItemTemplateSelector(context, attrs);

        adapter.ItemTemplateSelector = itemTemplateSelector;
        Adapter = adapter;

        if (itemTemplateSelector.GetType() == typeof(MvxDefaultTemplateSelector))
            ItemTemplateId = itemTemplateId;
    }
}

and in the CardView's RecyclerView, replace the default MvxRecyclerView to use this subclass.

Upvotes: 1

Related Questions