MvxListView checkable list item

陌路散爱 提交于 2019-12-07 13:32:14

问题


I wanted to get the CustomChoiceList to work with MvvmCross, but was struggling getting the sample working, the ListItem wouldn't get selected.

In fact the sample uses a custom LinearLayout that extends LinearLayout and implements ICheckable. When using the same layout with a MvxAdapter and an MvxListView the method OnCreateDrawableState is never called and the text and selection icon are never high-lighted.

I'm aware that the selected item could be stored in the ViewModel.

Here is the original sample: https://github.com/xamarin/monodroid-samples/tree/master/CustomChoiceList


回答1:


In fact the MvxAdapter class inflates the list item layout into a MvxListItemView behind the scenes, so you actually get an additional FrameLayout around your list item template. MvxListItemView doesn't implement ICheckable and therefore the information whether to check the item is not propagated.

The trick is to implement a custom MvxAdapter overwriting CreateBindableView and return a subclass of MvxListItemView that implements ICheckable. You also must set the android:duplicateParentState="true" int the root of the list item template (list_item.axml)

You can find the complete project here: https://github.com/takoyakich/mvvmcross-samples/tree/master/CustomChoiceList

Below the relevant changes:

list_item.axml:

<?xml version="1.0" encoding="utf-8"?>
<customchoicelist.CheckableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
    android:duplicateParentState="true"
...

Extended MvxAdapter:

class MyMvxAdapter : MvxAdapter {
        private readonly Context _context;
        private readonly IMvxAndroidBindingContext _bindingContext;

        public MyMvxAdapter(Context c) :this(c, MvxAndroidBindingContextHelpers.Current())
        {
        }
        public MyMvxAdapter(Context context, IMvxAndroidBindingContext bindingContext) :base(context, bindingContext)
        {
            _context = context;
            _bindingContext = bindingContext;
        }
        protected override MvxListItemView CreateBindableView(object dataContext, int templateId)
        {
            return new MyMvxListItemView(_context, _bindingContext.LayoutInflater, dataContext, templateId);
        }
    }

Extended MvxListItemView :

class MyMvxListItemView : MvxListItemView, ICheckable
{

    static readonly int[] CHECKED_STATE_SET = {Android.Resource.Attribute.StateChecked};
    private bool mChecked = false;

    public MyMvxListItemView(Context context,
                           IMvxLayoutInflater layoutInflater,
                           object dataContext,
                           int templateId)
        : base(context, layoutInflater, dataContext, templateId)
    {         
    }

    public bool Checked {
        get {
            return mChecked;
        } set {
            if (value != mChecked) {
                mChecked = value;
                RefreshDrawableState ();
            }
        }
    }

    public void Toggle ()
    {
        Checked = !mChecked;
    }

    protected override int[] OnCreateDrawableState (int extraSpace)
    {
        int[] drawableState = base.OnCreateDrawableState (extraSpace + 1);

        if (Checked)
            MergeDrawableStates (drawableState, CHECKED_STATE_SET);

        return drawableState;
    }
}


来源:https://stackoverflow.com/questions/18672562/mvxlistview-checkable-list-item

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!