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?

Hein Andre Grønnestad
  • 6,885
  • 2
  • 31
  • 43

3 Answers3

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" 
Ondřej Kunc
  • 1,087
  • 9
  • 17
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">
Martijn00
  • 3,569
  • 3
  • 22
  • 39
  • 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. – Hein Andre Grønnestad Jul 20 '15 at 10:39
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.

Trevor Balcom
  • 3,766
  • 2
  • 32
  • 51