MvxListView可检查列表项

时间:2013-09-07 10:55:13

标签: android-listview xamarin.android mvvmcross selected

我想让CustomChoiceList与MvvmCross一起使用,但是很难让样本正常工作,ListItem不会被选中。

实际上,该示例使用扩展LinearLayout并实现ICheckable的自定义LinearLayout。 当使用与MvxAdapter和MvxListView相同的布局时,永远不会调用OnCreateDrawableState方法,并且文本和选择图标永远不会高亮。

我知道所选项目可以存储在ViewModel中。

以下是原始样本: https://github.com/xamarin/monodroid-samples/tree/master/CustomChoiceList

1 个答案:

答案 0 :(得分:3)

实际上,MvxAdapter类将列表项布局扩展为幕后的MvxListItemView,因此您实际上会在列表项模板周围获得额外的FrameLayout。 MvxListItemView不实现ICheckable,因此不传播是否检查项目的信息。

诀窍是实现自定义MvxAdapter覆盖CreateBindableView并返回实现ICheckable的MvxListItemView的子类。 您还必须将android:duplicateParentState="true" int设置为列表项模板的根(list_item.axml)

您可以在此处找到完整的项目: https://github.com/takoyakich/mvvmcross-samples/tree/master/CustomChoiceList

以下相关变化:

list_item.axml:

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

扩展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);
        }
    }

扩展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;
    }
}