How do I bind to `ItemClick` for a `MvxLinearLayout`?
Asked Answered
B

3

6

I have a ScrollView which originally wrapped two MvxListView controls.

Having ListView controls in a ScrollView isn't supported by Android though, which makes sense, because they both try to fill the parent height and provide their own scrolling logic.

What I want is two unscrollable lists with their full height inside my ScrollView. ListView which MvxListView extends doesn't support this without hacking the height manually.

The reason I want this is because I have two separate lists that I have bound to separate sources and they both have their own header. I need all of this to be scrollable within one ScrollView.

Then I found MvxLinearLayout which is a bindable LinearLayout which has an ItemSource property I can bind to. It works excellent, it shows my items and get the full height of all items so I can scroll both my lists in my ScrollView. The problem is that it doesn't seem to have an ItemClick property, so I don't have a way to get user input from my list.

Does anyone know a clean way of doing this in a bindable manner? I don't want to attach onItemClick handlers in my code behind. Is there another MvvmCross control that can do what I want?

Bibliology answered 20/7, 2015 at 8:31 Comment(1)
I don't understand why you cannot populate all your data into a single ListView?Menthol
L
12

You can extend MvxLinearLayout to support ItemClick:

public class MvxClickableLinearLayout : MvxLinearLayout
{
    public MvxClickableLinearLayout(Context context, IAttributeSet attrs)
        : this(context, attrs, new MvxClickableLinearLayoutAdapter(context))
    {
    }

    public MvxClickableLinearLayout(Context context, IAttributeSet attrs, MvxClickableLinearLayoutAdapter adapter)
        : base(context, attrs, adapter)
    {
        var mvxClickableLinearLayoutAdapter = Adapter as MvxClickableLinearLayoutAdapter;
        if (mvxClickableLinearLayoutAdapter != null)
        {
            mvxClickableLinearLayoutAdapter.OnItemClick = OnItemClick;
        }
    }

    public ICommand ItemClick { get; set; }

    public void OnItemClick(object item)
    {
        if (ItemClick != null && ItemClick.CanExecute(item))
        {
            ItemClick.Execute(item);
        }
    }
}

Adapter:

public class MvxClickableLinearLayoutAdapter : MvxAdapterWithChangedEvent, View.IOnClickListener
{
    public delegate void ItemClickDelegate(object item);

    public ItemClickDelegate OnItemClick;

    public MvxClickableLinearLayoutAdapter(Context context)
        : base(context)
    {
    }

    public void OnClick(View view)
    {
        var mvxDataConsumer = view as IMvxDataConsumer;

        if (mvxDataConsumer != null && OnItemClick != null)
        {
            OnItemClick(mvxDataConsumer.DataContext);
        }
    }

    protected override View GetView(int position, View convertView, ViewGroup parent, int templateId)
    {
        View view = base.GetView(position, convertView, parent, templateId);
        view.SetOnClickListener(this);
        return view;
    }
}

Now you can bind to ItemClick just like you would do with a ListView:

local:MvxBind="ItemClick SomeCommand" 
Lucullus answered 22/7, 2015 at 15:2 Comment(2)
Is not working in MvvmCross 5.1 because the mvxDataConsumer is null when parsed (view as IMvxDataConsumer). Any idea of why?Homeless
use view?.Tag as IMvxDataConsumerLovel
P
0

You need to add a Click binding to the separate items inside the layout. You can add a Click to any layout like this:

<RelativeLayout
    android:background="?android:attr/selectableItemBackground"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/relativeLayout1"
    local:MvxBind="Click SomeCommand">
Purgative answered 20/7, 2015 at 10:16 Comment(1)
Hi, thanks for the reply. Yeah, I realize I can do that, but the whole point with the MvxLinearLayout is that it has an ItemsSource which is data bound, so it adds my items to the list automatically. To do what you propose I have to either make all the views for my items manually and bind to Click or loop through them after they get data bound automatically by the MvxLinearLayout, which isn't very clean from a MVVM perspective.Justificatory
P
0

Have you tried to specify an Item Template for the MvxLinearLayout? e.g., local:MvxItemTemplate="@layout/item_template"? You can setup the MvvmCross Click binding inside the Item Template on the controls you want to handle clicks for.

Pneumonia answered 21/7, 2015 at 21:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.