web-dev-qa-db-ja.com

EditTextアクションバーなしでポップアップのコピー/貼り付けをアクティブにする方法は?

私はデルファイの下でm Androidフレームワークを使用して編集を作成します。テーマをTheme.DeviceDefault.Light.NoActionBarに設定すると、 EditTextでテキストを選択すると、下の図に示すように、「すべて選択/切り取り/コピー/貼り付けなど」というポップアップが表示されます。

ただし、Theme.Material.Light.NoActionBarまたはTheme.Holo.Light.NoActionBarを選択すると、iEditText内のテキストを選択できません(右または左のテキスト選択ハンドルがありません)、もちろん、コピー/貼り付けのポップアップがありません

Theme_Material_Light_NoActionBarにこのコピー/貼り付けポップアップを表示する方法はありますか?

enter image description here Theme.DeviceDefault.Light.NoActionBar

enter image description here Theme_Material_Light_NoActionBar

enter image description here Theme.Holo.Light.NoActionBar

注1:

画面を水平に移動すると、edittextはすべての利用可能なスペースを取り、次に下の画像のように右と左のテキスト選択ハンドルが表示されますが、テーマがにスワップするためだと思いますTheme.DeviceDefault.Light.NoActionBar画面を水平に移動したが、よくわからない場合:

enter image description here

注2

私のeditTextで、setCustomSelectionActionModeCallback(new Callback(){})を実行すると、コールバックが呼び出されることはありません:(これは正常ではないと思いますか?editTextで禁止できること折り返し電話 ?

注2

すべてのテーマでテキストを選択できますが(もちろんそれをコピーすることはできません)、Theme.DeviceDefault.Light.NoActionBarを除いて、右と左のテキスト選択ハンドルが表示されません。

注3

Theme.DeviceDefault.Light.NoActionBarは、samsungギャラクシーのような一部の電話でのみ、右と左のテキスト選択ハンドルを表示します。他のいくつかではそれはうまくいきませんでした。

注4

問題の原因を部分的に見つけました!これは、WindowManager.addView(view、layout_params)を介してビューを作成し、このようにしてstartactionmodeforChildがnullを返し、アクションバーとテキスト選択ハンドルが表示されないようにするためです。今、私が私の編集テキストでこのようなことをした場合:

@Override
public ActionMode startActionMode(ActionMode.Callback callback) {
    Activity Host = (Activity) this.getContext();    
    return Host.getWindow().getDecorView().startActionMode(callback); 
} 

次に、右と左のテキストアクションハンドルを表示できます(ただし、マシュマロでは表示されません。これはLollipopでのみ機能するため、理由はわかりません)。私の問題は、アクションバーが表示されているが、空で表示されていることです:(内部には何も描画されていません(ただし、カット/コピー/過去のコントロールがダンプビュー階層の内部にあることがわかります)。したがって、今は方法を探していません。代わりに、このアクションバーをポップアップメニューに置き換えます(画像Theme.DeviceDefault.Light.NoActionBarなど)。

18
loki

あなたの活動に以下を追加する

ActionMode mActionMode;

そして、あなたはActionMondeCallbackインターフェースを作成する必要があります

class ActionBarCallback implements ActionMode.Callback
    {

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            mode.getMenuInflater().inflate(R.menu.contextual_menu, menu);
            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {

            int id = item.getItemId();
            if(id == R.id.item_delete)
            {
                tv.setText("");
                Toast.makeText(MainActivity.this,"option deleted",Toast.LENGTH_LONG);
            }
            return false;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {

        }
    }

ここで、contextual_menu.xmlは次のとおりで、必要なアイコンがあります

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    tools:context="com.example.letschat"
    >
    <item
        Android:id="@+id/item_search"
        Android:icon="@Android:drawable/ic_menu_search"
        app:showAsAction="ifRoom|withText"
        Android:title="Delete"
        Android:titleCondensed="Delete">
    </item>
    <item
        Android:id="@+id/item_delete"
        Android:icon="@Android:drawable/ic_menu_delete"
        app:showAsAction="ifRoom|withText"
        Android:title="Delete"
        Android:titleCondensed="Delete">
    </item>
    <item
        Android:id="@+id/item_share"
        Android:icon="@Android:drawable/ic_menu_share"
        app:showAsAction="ifRoom|withText"
        Android:title="Delete"
        Android:titleCondensed="Delete">
    </item>
</menu>

次に、Contextual ActionBar(CAB)を有効にします。たとえば、次のように、ここではテキストビューを長押しすると有効になります

yourtextView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                mActionMode = MainActivity.this.startActionMode(new ActionBarCallback());
                return true;
            }
        });

次に、CABの各アクションイベントをクリックして独自のアクションを作成する必要があります。

バウンティハンター詳細はこちら

5
W4R10CK

APIレベル11以上の場合、コピー、貼り付け、切り取り、カスタムコンテキストメニューの表示を停止できます。

_edittext.setCustomSelectionActionModeCallback(new ActionMode.Callback() {

        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        public void onDestroyActionMode(ActionMode mode) {                  
        }

        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            return false;
        }
    });
_

OnCreateActionMode(ActionMode、Menu)からfalseを返すと、アクションモード(すべて選択、切り取り、コピー、貼り付けアクション)が開始されなくなります。

解決策:EditTextでisSuggestionsEnabledおよびcanPasteをオーバーライドします。

簡単な解決策として、以下のクラスをコピーします。このクラスはEditTextクラスをオーバーライドし、それに応じてすべてのイベントをブロックします。

ざらざらした詳細については、読み続けてください。

解決策は、(文書化されていない)Android.widget.Editorクラスのshow()メソッドにPASTE/REPLACEメニューが表示されないようにすることです。メニューが表示される前に、(!canPaste &&!canSuggest)return;かどうかのチェックが行われます。これらの変数を設定するための基礎として使用される2つのメソッドは、どちらもEditTextクラスにあります。

isSuggestionsEnabled()はパブリックであるため、オーバーライドされる可能性があります。 canPaste()はそうではないため、派生クラスに同じ名前の関数を導入して非表示にする必要があります。したがって、これらの更新をsetCustomSelectionActionModeCallbackがあり、長押しが無効になっているクラスに組み込むと、カーソルを制御するためのすべての編集(ただし、テキスト選択ハンドラーは表示されます)を防ぐ完全なクラスがここにあります。

_package com.cjbs.widgets;

import Android.content.Context;
import Android.util.AttributeSet;
import Android.view.ActionMode;
import Android.view.Menu;
import Android.view.MenuItem;
import Android.widget.EditText;


/**
 *  This is a thin veneer over EditText, with copy/paste/spell-check removed.
 */
public class NoMenuEditText extends EditText

{
    private final Context context;

    /** This is a replacement method for the base TextView class' method of the same name. This 
     * method is used in hidden class Android.widget.Editor to determine whether the PASTE/REPLACE popup
     * appears when triggered from the text insertion handle. Returning false forces this window
     * to never appear.
     * @return false
     */
    boolean canPaste()
    {
       return false;
    }

    /** This is a replacement method for the base TextView class' method of the same name. This method
     * is used in hidden class Android.widget.Editor to determine whether the PASTE/REPLACE popup
     * appears when triggered from the text insertion handle. Returning false forces this window
     * to never appear.
     * @return false
     */
    @Override
    public boolean isSuggestionsEnabled()
    {
        return false;
    }

    public NoMenuEditText(Context context)
    {
        super(context);
        this.context = context;
        init();
    }

    public NoMenuEditText(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        this.context = context;
        init();
    }

    public NoMenuEditText(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        this.context = context;
        init();
    }

    private void init()
    {
        this.setCustomSelectionActionModeCallback(new ActionModeCallbackInterceptor());
        this.setLongClickable(false);
    }


    /**
     * Prevents the action bar (top horizontal bar with cut, copy, paste, etc.) from appearing
     * by intercepting the callback that would cause it to be created, and returning false.
     */
    private class ActionModeCallbackInterceptor implements ActionMode.Callback
    {
        private final String TAG = NoMenuEditText.class.getSimpleName();

        public boolean onCreateActionMode(ActionMode mode, Menu menu) { return false; }
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; }
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return false; }
        public void onDestroyActionMode(ActionMode mode) {}
    }
} 
_
4
W4R10CK

テーマを使用してみてくださいTheme.AppCompat.Light.NoActionBar
また、XMLファイルのEditTextにAndroid:textIsSelectable="true"を設定します。

2
dzikovskyy