Как программно закрыть контекстную панель выбора текста?

ИЗМЕНИТЬ:

Исходная проблема:

У меня есть фрагмент, который расширяет DialogFragment. В этом фрагменте я создаю AlertDialog и устанавливаю адаптер. Адаптер использует настраиваемый макет, чтобы сделать TextView доступными для выбора.

Теперь все в порядке, но после выбора текста и закрытия диалогового окна позже текст выделяется, но панель действий больше не отображается. Это можно исправить только путем повторного создания активности, которая запускает фрагмент.

tl;dr: использование статического диалога. После выделения текста и dismiss() текст можно выделить, но CAB нигде нет. Возможно, закрытие CAB программно может решить эту проблему. Как бы я это сделал?

Общий вопрос:

Я хотел бы узнать, как я могу вручную закрыть CAB выбора текста по умолчанию для Android (или получить ссылку на него).




Ответы (3)


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

Теперь, что касается моего общего вопроса, я решил его, установив обратные вызовы ActionMode для каждого convertView моего адаптера. Таким образом, я мог закрыть ActionMode в любое время между получением ссылки на режим (onCreateActionMode) и очисткой ссылки (onDestroyActionMode). Вот код:

public ActionMode mActionMode;

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // (Re)Use the convertView
    ViewHolder holder;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.popup_list_item, parent, false);
        holder = new ViewHolder();
        holder.textView = (TextView) convertView.findViewById(R.id.popupItem);
        holder.textView.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                mActionMode = mode;
                // Can now use the mode whenever (if it's not null)
                // e.g. call mActionMode.finish()
                return true; // true = create the ActionMode
            }

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

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

            @Override
            public void onDestroyActionMode(ActionMode mode) {
                mActionMode = null;
            }
        });
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    // Set text
    if (mQuery != null)
        holder.textView.setText(Html.fromHtml(getItem(position)));
    else
        holder.textView.setText(getItem(position));

    return convertView;
}

Однако мне не удалось решить мою первоначальную проблему (даже после того, как я смог закрыть ActionMode вручную), поэтому я был вынужден отказаться от использования статического диалога.

Я открыт для предложений о том, как решить мою первоначальную проблему, если у кого-то есть.

person Simas    schedule 07.08.2014
comment
Я даже не знал, что есть такая вещь, как setCustomSelectionActionModeCallback, но она все равно не дает вам ActionMode. Но то, что вы здесь делаете, плохо. Вы на самом деле не должны обращаться с CAB таким образом, я не удивлен, что вы столкнулись с проблемами. Обработайте CAB в своем Fragment один раз для всех элементов в списке. - person Xaver Kapeller; 07.08.2014
comment
@XaverKapeller На самом деле да, он дает мне ActionMode, как только выделен какой-либо текст. Я могу сохранить ссылку @ onPrepareActionMode или onCreateActionMode, а затем очистить эту ссылку @ onDestroyActionMode. Между первыми двумя и последним методом я могу вызвать метод mode.finish(), и он делает именно то, что я хотел с моим общим вопросом. - person Simas; 07.08.2014
comment
Конечно, вы получаете это внутри ActionMode.Callback, это не главное. Я просто говорю, что вам действительно не следует реализовывать такой CAB. - person Xaver Kapeller; 07.08.2014
comment
@XaverKapeller Я не реализую CAB. Я изменяю существующий CAB-файл Android единственным способом, который я нашел возможным. Спасибо за ваше время и знания. :-) - person Simas; 07.08.2014
comment
Я не внедряю CAB. Я изменяю существующий CAB-файл Android единственным возможным способом. Понятия не имею, что это должно означать, но CAB следует обрабатывать глобально, а не для каждого TextView в отдельности. Это плохо. Действительно плохо. Я просто не понимаю, почему вы не открываете правильный CAB в OnItemLongClick. Как будто это кажется более сложным и более подверженным ошибкам. - person Xaver Kapeller; 07.08.2014
comment
И я думаю, мне не нужно упоминать, что обработка CAB никогда не должна быть в Adapter... В конце концов, Adapter не имеет ничего общего с CAB... - person Xaver Kapeller; 07.08.2014
comment
@XaverKapeller 1. Я хочу изменить этот встроенный CAB вместо того, чтобы создавать свой собственный. 2. Если вы знаете, как я могу начать, пожалуйста, скажите 3. Пожалуйста, воздержитесь от комментариев, если у вас нет лучшего решения. Без обид, но это то, что работает для меня, и я еще не видел лучшего способа сделать это. - person Simas; 07.08.2014
comment
Похоже, ваше основное заблуждение заключается в том, что вы каким-то образом повторно используете или расширяете уже существующий CAB. Но вы не. Вы просто не настраиваете пользовательское меню, поэтому отображается меню по умолчанию. Я отредактирую свой ответ с правильным решением. - person Xaver Kapeller; 07.08.2014
comment
Но просто для уверенности: у вас есть Dialog в DialogFragment, а в этом Dialog вы отображаете ListView? - person Xaver Kapeller; 07.08.2014

На этот вопрос было бы легче ответить, если бы вы показали нам код, с помощью которого вы открываете CAB, но в целом это работает так:

После того, как вы реализовали свой ActionMode.Callback, вы открываете CAB следующим образом:

getActivity().startActionMode(new ActionModeCallbackImpl());

Но startActionMode() возвращает объект ActionMode, который вы можете сохранить в переменной:

ActionMode actionMode = getActivity().startActionMode(new ActionModeCallbackImpl());

С помощью этого объекта ActionMode вы можете позже закрыть CAB следующим образом:

actionMode.finish();

Я надеюсь, что смог помочь вам, и если у вас есть другие вопросы, пожалуйста, не стесняйтесь спрашивать!

person Xaver Kapeller    schedule 07.08.2014
comment
Проблема в том, что у меня не открывается CAB. Он автоматически открывается системой Android, когда я долго нажимаю TextView. Если бы я открыл CAB сам, конечно, я бы смог получить ссылку и закрыть его в любое время. - person Simas; 07.08.2014
comment
Тем не менее покажите нам соответствующий код. Пока я не вижу вашего кода, я могу только догадываться, в чем может быть проблема. - person Xaver Kapeller; 07.08.2014
comment
Я нашел свою проблему, поэтому теперь мой вопрос становится более общим: как я могу получить ссылку на открытый CAB-выделенный текст. - person Simas; 07.08.2014
comment
Я не думаю, что это возможно. - person Xaver Kapeller; 07.08.2014
comment
Это. Смотрите мой ответ, если вам интересно. - person Simas; 07.08.2014
comment
@user3249477 user3249477 Нет, вы никогда не получите ActionMode в своем ответе. - person Xaver Kapeller; 07.08.2014

у меня была такая же проблема. Я не хотел, чтобы CAB появлялся, поэтому я отключил его.

Проверьте это ответ

person Dilroop Singh    schedule 26.12.2015