1

EDIT:

Initial problem:

I have a fragment that extends a DialogFragment. In this fragment I create an AlertDialog and set an adapter. The adapter uses a custom layout to make the TextViews selectable.

Now it's all fine and dandy but after selecting some text and dismissing the dialog, later the text is selected but the action bar is not shown anymore. It can be fixed only by re-creating the activity which starts the fragment.

tl;dr: Using a static dialog. After text selection and dismiss(), the text can be selected but the CAB is nowhere to be found. Perhaps closing the CAB programatically can solve this. How would I do that?

General question:

I would like to find out how I can manually close the default android text selection CAB (or get a reference to it).

Simas
  • 43,548
  • 10
  • 88
  • 116

3 Answers3

3

I solved my initial problem by creating a new dialog for each fragment. Using a static dialog somehow messed up my text selection. It's too bad though as I now have to do a bunch of adjustments everytime I start the DialogFragment.

Now for my general question I solved that by setting ActionMode callbacks to each convertView of my adapter. That way I was able to close the ActionMode anytime between getting the reference to the mode (onCreateActionMode) and clearing the reference (onDestroyActionMode). Here's the code:

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;
}

However I failed to solve my initial problem (even after being able to close the ActionMode manually), so I was forced to drop the usage of a static Dialog.

I am open to suggestions, on how to solve my initial problem, if anyone has any.

Simas
  • 43,548
  • 10
  • 88
  • 116
  • I didn't even know there was such a thing as `setCustomSelectionActionModeCallback` but it still doesn't give you the `ActionMode`. **But** what you are doing here is bad. You **really shouldn't** handle the CAB like this, I am not surprised you ran into problems. Handle the CAB in your `Fragment` once for all items in the list. – Xaver Kapeller Aug 07 '14 at 16:52
  • @XaverKapeller Actually yes it does give me the ActionMode as soon as some text is selected. I am able to save the reference @ `onPrepareActionMode` or `onCreateActionMode` and then clear that reference @ `onDestroyActionMode`. Between the first two and the last method I can call mode.finish() and it does exactly what I wanted with my *general* question. – Simas Aug 07 '14 at 17:00
  • Of course you get it inside the `ActionMode.Callback` that is not the point. I'm just saying you really shouldn't implement a CAB like this. – Xaver Kapeller Aug 07 '14 at 17:03
  • @XaverKapeller I'm not implementing a CAB. I am modifying the existing android's CAB in *the only way* I found *possible*. Thank you for your time and knowledge. :-) – Simas Aug 07 '14 at 17:06
  • "I'm not implementing a CAB. I am modifying the existing android's CAB in the only way I found possible". No idea what that's supposed to mean, but CAB should be handled globally, not for each `TextView` individually. This is bad. Really bad. I just don't understand why you are not opening a proper CAB in `OnItemLongClick`. Like this seems more complicated and more error prone. – Xaver Kapeller Aug 07 '14 at 17:09
  • And I think I don't have to mention that CAB handling should never be in an `Adapter`... The `Adapter` has after all nothing to do with the CAB... – Xaver Kapeller Aug 07 '14 at 17:12
  • @XaverKapeller 1. I want to modify that built-in CAB instead of creating my own. 2. If you know how I can start it please do tell 3. Please restrain yourself from commenting if you don't have a better solution. No offense, but this is what works for me and I am yet to see a better way of doing it. – Simas Aug 07 '14 at 17:24
  • Your main misconception seems to be that you are somehow reusing or extending an already existing CAB. But you are not. You are just not setting a custom menu so the default one is displayed. I will edit my answer with a proper solution. – Xaver Kapeller Aug 07 '14 at 17:34
  • But just to be sure: You have a `Dialog` in a `DialogFragment` and in that `Dialog` you display a `ListView`? – Xaver Kapeller Aug 07 '14 at 17:35
0

This question would be easier to answer if you had shown us the code with which you open the CAB, but in general it works like this:

After you implemented your ActionMode.Callback you open the CAB like this:

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

But startActionMode() returns an ActionMode object which you can save in a variable:

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

With this ActionMode object you can later on close the CAB` like this:

actionMode.finish();

I hope I could help you and if you have any other questions please feel free to ask!

Xaver Kapeller
  • 49,491
  • 11
  • 98
  • 86
0

i had same issue. i dont wanted CAB to Appear so i styled it off.

Check this answere

Community
  • 1
  • 1
Dilroop Singh
  • 544
  • 6
  • 16