事实上,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;
}
}