меню - menu add android




Отключить контекстное меню EditText (4)

Я делаю вертикальный EditText для традиционного монгола. Я успешно реализовал его, ViewGroup слегка измененный EditText внутри повернутой ViewGroup . Мне нужно создать полностью настраиваемое контекстное меню, потому что система не поддерживает вертикальный текст и не поворачивается при повороте ViewGroup . Поэтому я хочу полностью отключить контекстное меню системы.

Обратите внимание, что это отличается от этих вопросов, которые просто пытаются отключить копирование / вставку / etc .:

Хотя я не получаю контекстное меню, появляющееся в симуляторе, я получаю его на моем Android 5.0.2 Xiaomi.

Я пытался:

  • setCustomSelectionActionModeCallback "решение"
  • setLongClickable(false); "решение"
  • решение onTouchEvent "

Я открыт для взлома, но мне нужно, чтобы он постоянно работал на разных устройствах. Марк Мерфи (Commons Guy) написал некоторое время назад в ответ другому пользователю, пытающемуся сделать что-то похожее:

Я подозреваю, что даже если вы придумаете ответ, он не будет работать через устройства. Производители устройств имели тенденцию сворачивать свое «контекстное меню» для EditText, победив попытки разработчиков добавлять элементы в это контекстное меню. Я предполагаю, что попытка блокировать это контекстное меню будет иметь похожие результаты.

Мне повезло?

Единственное, о чем я могу сейчас думать, это полностью переписать TextView и EditText с нуля (ну, изменив исходный код Android). Я знаю кого-то другого, кто сделал что-то подобное, но его код не является открытым исходным кодом. Прежде чем я сделаю этот важный шаг, я хочу попытаться попросить более простое решение здесь в Stack Overflow.

Обновление: я пытался изменить исходный код TextView течение последних двух дней, и он выглядит как 6-месячный проект. Это масса взаимосвязанных классов. Мне нужно другое решение, но у меня нет идей.

MVCE

Это самый простой способ подумать о том, чтобы воссоздать проблему. Из моего настраиваемого EditText ничего не нужно. В макете есть один EditText сделанный путем замены проекта Hello World TextView по умолчанию. Я изменил min API до 11, чтобы избежать использования устаревших методов.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EditText editText = (EditText) findViewById(R.id.edit_text);
        editText.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
            @Override
            public boolean onCreateActionMode(ActionMode actionMode, Menu menu) { return false; }
            @Override
            public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) { return false; }
            @Override
            public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) { return false; }
            @Override
            public void onDestroyActionMode(ActionMode actionMode) { }
        });
    }
}

Контекстное меню в симуляторе (работает API 24) по-прежнему отображается, когда я нажимаю на дескриптор курсора (но не на длинный клик или двойной щелчок). Вот изображение:

На моем телефоне Xiaomi MIUI под управлением Android 5.0 я получаю контекстное меню во всех ситуациях (щелчок курсора, длинный клик, двойной щелчок).

Обновить

Решение Aritra Roy работает в симуляторе, на некоторых других устройствах, которые он тестировал, и на моем устройстве. Я принял его ответ, потому что он решает мою оригинальную проблему. Единственным отрицательным побочным эффектом является то, что выбор текста также отключен.


Вам нужно сделать три вещи.

ШАГ 1

Вы можете отключить отображение контекстных меню, возвращая false из этих методов,

mEditEext.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;
            }
        });

ШАГ 2

Необходимо также отключить длительный щелчок в EditText.

mEditText.setLongClickable(false);

или делать это, android:longClickable="false" в XML.

ШАГ 3

Теперь вам нужно запретить появлению меню при щелчке по ручкам. Решение прост,

1) Расширьте класс EditText ,

2) Override isSuggestionsEnabled() и возвращает false ,

3) Создайте метод canPaste() и верните false . Это метод скрывается.

БЫСТРЫЙ РЕШЕНИЕ

Если вы не хотите делать все это вручную. Вот специальный класс EditText, который вы можете использовать, чтобы быстро это сделать. Но я все же рекомендую вам пройти один шаг, чтобы понять, как все работает.

public class MenuHidingEditText extends EditText {
    private final Context mContext;

    public MenuHidingEditText(Context context) {
        super(context);
        this.mContext = context;

        blockContextMenu();
    }

    public MenuHidingEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;

        blockContextMenu();
    }

    public MenuHidingEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.mContext = context;

        blockContextMenu();
    }

    private void blockContextMenu() {
        this.setCustomSelectionActionModeCallback(new BlockedActionModeCallback());
        this.setLongClickable(false);
        this.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                MenuHidingEditText.this.clearFocus();
                return false;
            }
        });
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            // setInsertionDisabled when user touches the view
            this.setInsertionDisabled();
        }
        return super.onTouchEvent(event);
    }

    private void setInsertionDisabled() {
        try {
            Field editorField = TextView.class.getDeclaredField("mEditor");
            editorField.setAccessible(true);
            Object editorObject = editorField.get(this);

            Class editorClass = Class.forName("android.widget.Editor");
            Field mInsertionControllerEnabledField = editorClass.getDeclaredField("mInsertionControllerEnabled");
            mInsertionControllerEnabledField.setAccessible(true);
            mInsertionControllerEnabledField.set(editorObject, false);
        }
        catch (Exception ignored) {
            // ignore exception here
        }
    }

    @Override
    public boolean isSuggestionsEnabled() {
        return false;
    }

    private class BlockedActionModeCallback implements ActionMode.Callback {

        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) {
        }
    }
}

Вот как вы блокируете меню копирования пасты в любом виде, форме или форме. Эта ошибка действительно сводила меня с ума, и, как и с любой ошибкой Samsung, вы знаете ее в своем коде, но вы также знаете, что они не исправит ее в ближайшее время. В любом случае, вот чудо-стена ...

  1. Убедитесь, что Android.Build.Model.toLowerCase (). StartWith ('sm-g930'). Не совпадают со всей строкой, последняя буква - это младший идентификатор версии. Я сохранил эту логическую переменную в переменной shouldBlockCopyPaste, которая появляется позже.

  2. Если это соответствует, вы хотите заблокировать меню копирования вставки. Вот как вы НАСТОЯТЕЛЬНО ДЕЛАЕТЕ ЭТО !!!

Переопределите эти 2 функции, вы заметите, что мой mustBlockCopyPaste логичен, так что другие устройства не блокируются.

   @Override
   public ActionMode StartActionMode (ActionMode.Callback callback){
      if (shouldBlockCopyPaste) {
        return null;
      } else {
        return super.StartActionMode(callback);
      }
    }

   @Override
   public ActionMode StartActionMode (ActionMode.Callback callback, int type){
      if (shouldBlockCopyPaste) {
        return null;
      } else {
        return super.StartActionMode(callback, type);
      }
    }

попробуй это

mEditText.setClickable(false);
mEditText.setEnabled(false);

ОБНОВИТЬ

Попробуйте это решение, расширив Edittext,

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

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) {}
}
}

Ссылка: https://.com/a/28893714/5870896


mEditText.setLongClickable(false);

Это самый простой способ отключить редактируемый текст.





mongolian-vertical-script