📘

.NET MAUIだって、文字入力時のメニュー欄に項目追加したい!(Android)

2022/10/19に公開

ほぼ、こちらのサイトの内容を、.NET MAUI用に書き換えた話になります。

やりたいこと

文字入力欄で入力中に文字選択すると「コピー」だとか「すべて選択」とか出てくるメニュー欄(AndroidだとActionModeと言っているやつ)に、自分なりのメニューを追加したい話。

実装コード

TextViewのCustomSelectionActionModeCallbackを使ってやれば出来る。
Android.Views.ActionMode.Callback2を継承したものが必要なので、適当に下記の通り書く。

OnCreateActionModeに、menuにaddすれば、メニュー内容を追加できる。
OnActionItemClickedは、メニューのボタンを押すと実行される。ので、Android.Views.IMenuItem itemを使って、どんなボタンが押されたか判断して、処理を追加。
今回は、Sizeボタンを押すと、選択文字を取得して、コンソール上に表示するという感じにした。

public class TextViewSelect_ActionMode : Android.Views.ActionMode.Callback2
{
	Android.Widget.TextView ViewObject { set; get; }
	public TextViewSelect_ActionMode(Android.Widget.TextView ViewObject)
	{
		this.ViewObject = ViewObject;
	}

	public override bool OnCreateActionMode(Android.Views.ActionMode mode, Android.Views.IMenu menu)
	{
		menu.Add(new Java.Lang.String("Size"));
		return true;
	}

	public override bool OnPrepareActionMode(Android.Views.ActionMode mode, Android.Views.IMenu menu)
	{
		return false;
	}

	public override bool OnActionItemClicked(Android.Views.ActionMode mode, Android.Views.IMenuItem item)
	{
		int min = 0;
		int max = ViewObject.Text.Length;
		if (ViewObject.IsFocused)
		{
			min = Math.Max(0, Math.Min(ViewObject.SelectionStart, ViewObject.SelectionEnd));
			max = Math.Max(0, Math.Max(ViewObject.SelectionStart, ViewObject.SelectionEnd));
		}
		string selectedText = ViewObject.Text.Substring(min, max - min);


		if("Size" == item.TitleFormatted.ToString()) {
			Console.WriteLine("Size Push! : " + selectedText);
		}

		// 元からあるコピーだとかに、処理を追加したければ、こっちをやる
		//switch (item.ItemId)
		//{
		//	case Android.Resource.Id.Copy:
		//		return true;	
		//}

		return true;
	}

	public override void OnDestroyActionMode(Android.Views.ActionMode mode)
	{
		return;
	}
	public override void OnGetContentRect(Android.Views.ActionMode mode, Android.Views.View view, Android.Graphics.Rect outRect)
	{
		base.OnGetContentRect(mode, view, outRect);
	}

}

下記の物は、Handler.MauiContextを使っているので、一度描画させた後に、実行させてください。

// 入力時のメニュー欄を作る
Android.Widget.TextView view = ((Android.Widget.TextView)this.TextEditor.ToPlatform(this.TextEditor.Handler.MauiContext));
if (view.CustomSelectionActionModeCallback == null)
{
	view.CustomSelectionActionModeCallback = new TextViewSelect_ActionMode(view);
	//view.CustomInsertionActionModeCallback = new ****************; // これやると、挿入作業時のメニューを編集できる。
}

なお、CustomSelectionActionModeCallbackは、文字を選択している時のメニューに使用されるが、CustomInsertionActionModeCallbackは、文字を選択してないカーソルの表示の時のメニューに使用される。

オワリ

\(^o^)/

Discussion