关于 xamarin.android:How to create view’s actions listener for MvxItemTemplate

How to create view's actions listener for MvxItemTemplate

我有一个包含 MvxListView 和表单的视图。我可以在我的视图代码中使用以下代码隐藏软键盘(因为这是纯视图问题)

1
2
3
4
5
6
7
8
9
10
var editText = FindViewById<EditText>(Resource.Id.newCheckbookName);
editText.EditorAction += (object sender, TextView.EditorActionEventArgs e) =>
    {
        if (e.ActionId == ImeAction.Done)
        {
            InputMethodManager inputMgr = GetSystemService(InputMethodService) as InputMethodManager;
            inputMgr.HideSoftInputFromWindow(CurrentFocus.WindowToken, 0);
        }
        return;
   };

在我的项目模板中,我有另一个文本编辑器,并且希望具有相同的行为。但是我在哪里可以添加我的代码,因为我没有 MwxItemTemplate 的任何视图代码?


我认为最简单的方法是在列表项中使用自定义"视图"。

注意:这里的 \\'View\\' 指的是 Android 视图 - 不是 Model-View-ViewModel 视图 - 抱歉命名混乱!

创建自定义视图很容易...

只需创建一个自定义视图 - 例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
namespace Angevelle.App1.UI.Droid.Controls
{
    public class MyText : EditText
    {
        public MyText(Context context, IAttributeSet attrs)
            : base(context, attrs)
        {
            this.EditorAction += OnEditorAction;
        }

        private void OnEditorAction(object sender, EditorActionEventArgs editorActionEventArgs)
        {
            if (editorActionEventArgs.ActionId == ImeAction.Done)
            {
                // this code not tested - but something like this should work
                var imm = (InputMethodManager)Context.GetSystemService(Context.InputMethodService);
                imm.HideSoftInputFromWindow(WindowToken, 0);
            }
        }
    }
}

然后您可以在 AXML 中使用该视图,就像使用 Android 或 Mvx 视图一样:

1
2
3
<angevelle.app1.ui.droid.controls.MyText
         android:layout_height=....
     />

如果您发现 angevelle.app1.ui.droid.controls 过于冗长,那么您可以使用 setup.cs 中的缩写来缩短它:

1
2
3
4
5
6
7
8
9
    protected override IDictionary<string, string> ViewNamespaceAbbreviations
    {
        get
        {
            var abbreviations = base.ViewNamespaceAbbreviations;
            abbreviations["Abv"] ="angevelle.app1.ui.droid.controls";
            return abbreviations;
        }
    }

那么你可以使用:

1
2
3
<Abv.MyText
         android:layout_height=....
     />

另一种方法可能是以某种方式自定义列表...

如果您确实需要完全自定义列表视图及其适配器,那么可以使用相同类型的技术轻松完成 - 从您的 UI 项目中的 MvxBindableListView 继承:

1
2
3
4
5
6
7
public class MyListView : MvxBindableListView
{
        public MyListView(Context context, IAttributeSet attrs);
            : base(context, attrs, new MyListAdapter(context))
        {
        }
}

其中 MyListAdapter 覆盖视图创建:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MyListAdapter : MvxBindableListAdapter
{
    public MyListAdapter(Context context)
        : base(context)
    {
    }

    // put your custom Adapter code here... e.g.:
    protected override MvxBindableListItemView CreateBindableView(object source, int templateId)
    {
        return new MySpecialListItemView(_context, _bindingActivity, templateId, source);
    }
}

其中 MySpecialListItemView 继承自 MvxBindableListItemView 但添加了您自己的自定义功能。

使用这种方法,您的列表将从:

1
2
3
<Mvx.MvxBindableListView
      ....
     />

到:

1
2
3
<Abv.MyListView
      ....
     />

有关自定义视图的更多示例,请查看 GitHub - 例如在 https://github.com/Cheesebaron

中的一些 Calendar、ColorPicker、ActionBar 项目中

不要期望您的自定义控件在 xamarin 设计器中呈现(嗯,还没有...)

最后两个音符...

  • 要重用代码...您可能希望以某种方式将该 HideSoftInputFromWindow 功能放在扩展方法中,以便您可以调用 anyEditText.HideOnDone()

  • 在 Views/UIViews 上使用 Monodroid/monotouch 事件时要小心——这些事件往往使用本机委托/侦听器——因此有时您会发现附加某些内容以订阅一个事件可能会取消附加其他内容!通常,只要您不在本地侦听器/委托处理程序的同时混合和匹配 C# 事件订阅,您就可以了。