EditTextで選択された文字を加工する

TextEdit内で文字列が範囲選択された場合に次のような選択メニューが出てきます。

テキスト選択メニューの画像

このメニューは自由に変更することができ、独自の機能を持つメニューを追加することができます。

ここではそのカスタマイズ方法を紹介します。

アイテムIDの作成

まず、res/values/以下のフォルダに名前は何でも良いですが、ここではmy_select_menu.xmlなどの名前でファイルを作成します。

そこに次のようにアイテムタグを追加します。

<?xml version="1.0" encoding="utf-8" ?>
<resources>
    <item
        type="id" 
        name="marker_menu" />
</resources>

これで"marker_menu"というIDができました。

メニューの追加

では、次に特定のEditTextに対してテキスト選択メニューを改造していきます。

メニュー改造には次のようにEditTextに対してsetCustomSelectionActionModeCallbackメソッド(APIレベル11以上)を使います。

EditText editText = (EditText)findViewById(R.id.editText);

editText.setCustomSelectionActionModeCallback(new ActionMode.Callback()
{
    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu)
    {
        return false;
    }
    
    @Override
    public void onDestroyActionMode(ActionMode mode){}
    
    //テキスト選択画面のアイテム追加
    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) 
    {
        menu.removeItem(android.R.id.paste);  
        menu.removeItem(android.R.id.cut);  
        menu.removeItem(android.R.id.copy);
            //順にペースト、カット、コピーのメニューアイテムを削除
    
        MenuItem markerItem = menu.add(Menu.NONE, R.id.marker_menu, Menu.NONE, "Mark Text");
            //メニュー追加
        markerItem.setIcon(R.drawable.marker_icon);
            //アイコン設定
            return true;
        }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) 
    {
        String text = editText.getText().toString();
        
        //選択位置のはじめと終わりを取得
        int start = 0, end = 0;
        if(editText.isFocused()){
            start = editText.getSelectionStart();
            end = editText.getSelectionEnd();
        }
        switch(item.getItemId()){
        case R.id.marker_menu:
            String selectText = text.substring(start, end);
            editText.setText(Html.fromHtml("SELECT " + text.substring(0, start) + "<font color=\"red\">" + text.substring(start, end) + "</font>" + text.substring(end)));
                //選択した部分の文字色を赤色に変える。
            return true;
        }

        return false;
    }
});

コードの説明

新たにアイテムを追加するために空きを作る必要があるのでコピーやカットなどのメニューは次のようなコードで削除します。

menu.removeItem(android.R.id.paste);  

そして、新たにアイテムを追加しているのが次のコードです。

MenuItem markerItem = menu.add(Menu.NONE, R.id.marker_menu, Menu.NONE, "Mark Text");
    //メニュー追加
markerItem.setIcon(R.drawable.marker_icon);
    //アイコン設定

addメソッドでMenu.NONEというフラグを渡していますが、これは子アイテムを持たないことを示しています。

また、"Mark Text"のようなアイテム名はアイコンを設定した場合、アイテムが長押しされたときのみアイテム名が表示されるようになります。

メニューを追加したらonActionItemClickedメソッド内で押されたアイテムのIDを取得して文字色を変えていて、以下がそのコードです。

switch(item.getItemId()){
case R.id.marker_menu:
    String selectText = text.substring(start, end);
    editText.setText(Html.fromHtml(text.substring(0, start) + 
                "<font color=\"red\">" + text.substring(start, end) 
                + "</font>" + text.substring(end)));
        //選択した部分の文字色を赤色に変える。
    return true;
}

startが選択の開始位置、endが選択終了の位置です。

開始と終了位置にfontタグをはさみ、それをfromHtmlでHTMLテキストに変換してからエディットテキストに表示しています。

今回カスタムしたアイテム欄は次の画像のようになりました。

カスタマイズしたメニューの画像

赤鉛筆マークが追加したアイテムです。

関連項目
プライバシーポリシー