简体   繁体   中英

How to override Contextual Action Bar when selecting text in a WebView in Android?

I've googled a lot, and find some tutorials and answers here in stackoverflow, but I am facing some difficults to resolve this issue.

I have a Fragment with a WebView, and I want to show my custom Contextual Action Bar when the user selects some text of my web view. I have two main issues here:

  • 1 Currently, my custom CAB is showed when the user performs long click in any part of the web view.
  • 2 The text is not selected when the user performs long click in some text of my web view.

Some of my current code:

Custom interface:

public class SelectActionModeCallback implements ActionMode.Callback {

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

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

Custom WebView

public class CustomWebView extends WebView {

    private SelectActionModeCallback actionModeCallback;

    public CustomWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public ActionMode startActionMode(Callback callback) {
        actionModeCallback = new SelectActionModeCallback();
        return super.startActionMode(actionModeCallback); 
    }

In my fragment, I have this:

@Override
public void onResume() {
    super.onResume();

    myWebView.setOnLongClickListener(new View.OnLongClickListener() {
        public boolean onLongClick(View view) {
            if (mActionMode != null) {
                Toast.makeText(getActivity(), "test", Toast.LENGTH_SHORT).show();
                return false;
            }

            mActionMode = getActivity().startActionMode(mActionModeCallback);
            view.setSelected(true);
            return true;
        }
    });
}

private SelectActionModeCallback mActionModeCallback = new SelectActionModeCallback() {

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

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

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_sustom:
                customMethod();
                mode.finish();
                return true;
            default:
                return false;
        }
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        mActionMode = null;
    }
};

THERE IS A BETTER WAY! See the following answer: https://stackoverflow.com/a/22391169/2608235


In short, you can't use an OnLongClickListener and keep the selection within a WebView . Android does some weird stuff behind the scenes for selecting text within WebViews . If you override OnLongClickListener in order to call startActionMode , you will lose the selection, as you have found out.

What you should do instead is override startActionMode in your fragment, rather than its parent View (in your case, CustomWebView ).

I don't have the mod permission to mark this question as a duplicate, but it is.
See my question for more info: Use a custom contextual action bar for WebView text selection

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM