3

CustomChoiceList を MvvmCross で動作させたいと思っていましたが、サンプルを動作させるのに苦労しており、ListItem が選択されませんでした。

実際、このサンプルでは、​​LinearLayout を拡張して ICheckable を実装するカスタム LinearLayout を使用しています。MvxAdapter と MvxListView で同じレイアウトを使用する場合、メソッド OnCreateDrawableState が呼び出されることはなく、テキストと選択アイコンが強調表示されることはありません。

選択したアイテムが ViewModel に格納される可能性があることは承知しています。

元のサンプルは次のとおりです: https://github.com/xamarin/monodroid-samples/tree/master/CustomChoiceList

4

1 に答える 1

3

実際、MvxAdapter クラスはリスト アイテム レイアウトを MvxListItemView にバックグラウンドで拡張するため、実際にはリスト アイテム テンプレートの周りに追加の FrameLayout を取得します。MvxListItemView は ICheckable を実装していないため、アイテムをチェックするかどうかの情報は伝達されません。

秘訣は、CreateBindableView を上書きするカスタム MvxAdapter を実装し、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;
    }
}
于 2013-09-07T10:55:12.570 に答える