2

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

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 的任何视图代码?

4

1 回答 1

2

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

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

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

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

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 视图一样:

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

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

    protected override IDictionary<string, string> ViewNamespaceAbbreviations
    {
        get
        {
            var abbreviations = base.ViewNamespaceAbbreviations;
            abbreviations["Abv"] = "angevelle.app1.ui.droid.controls";
            return abbreviations;
        }
    }

那么你可以使用:

<Abv.MyText
         android:layout_height=....
     />

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

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

public class MyListView : MvxBindableListView
{
        public MyListView(Context context, IAttributeSet attrs);
            : base(context, attrs, new MyListAdapter(context))
        {
        }
}

其中 MyListAdapter 覆盖视图创建:

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 但添加了您自己的自定义功能。

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

<Mvx.MvxBindableListView
      ....
     />

到:

<Abv.MyListView
      ....
     />

有关自定义视图的更多示例,请查看 GitHub - 例如https://github.com/Cheesebaron中的一些 Calendar、ColorPicker、ActionBar 项目

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


最后的两个注释...

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

  2. 在 Views/UIViews 上使用 Monodroid/monotouch 事件时要小心——这些事件倾向于使用本机委托/侦听器——所以有时你会发现附加一些东西来订阅一个事件可能会取消附加一些东西!通常,只要您不将 C# 事件订阅与本机侦听器/委托处理程序同时混合和匹配,您就可以了。

于 2012-10-17T13:32:20.490 回答