Frage

I have a TextView. When it is long-clicked, the piece of text over which the long-click was done should be highlighted and a contextual action menu should come up that gives some additional options.

However, if the text is highlighted the contextual action menu is different from what is required. On the other hand, if the desired contextual action menu is shown, the text is not highlighted.

I have been able to zero it down to the return statement in the onLongClick function in the onLongClickListener. Specifically, if the onLongClick function returns true (consumes the click), then the contextual action menu is shown but since the long click was never passed to the text selection tool, it does not get activated. However, if the onLongClick function returns false, the click is passed on to a function that triggers default behavior of copy + paste the text with selection.

The code:

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;

public class HelloTxtView extends Activity {

    //private EditText ed;
    private TextView ed;

    //actionmode callback.
    private ActionMode mActionMode;
    private ActionMode.Callback mActionModeCallback;

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

        ed = (TextView) findViewById(R.id.txtview);
        ed.setFocusable(true);
        ed.setText("Hello World! Let's select some text!!");

        initActionModeCallbacks();

        ed.setOnLongClickListener(new View.OnLongClickListener() {

            @Override
            public boolean onLongClick(View v) {
                Log.v(this.toString(), "Long click.");
                ed.setCursorVisible(true);

                Log.v(this.toString(), "Starting actionmodecallback.");
                mActionMode = HelloTxtView.this.startActionMode(mActionModeCallback);
                v.setSelected(true);

                return false;
            }
        });
    }

    public void initActionModeCallbacks() {

        /*
         * This function initializes the callbacks.
         */

        mActionModeCallback = new ActionMode.Callback() {

            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                //nothing to do here.
                Log.v(this.toString(), "Preparing action mode.");
                return false;
            }

            @Override
            public void onDestroyActionMode(ActionMode mode) {
                Log.v(this.toString(), "Destroy action mode.");
                //mActionModeCallback = null;
            }

            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                Log.v(this.toString(), "Creating new action mode menu.");
                //inflate a new menu.
                MenuInflater inflater = mode.getMenuInflater();
                inflater.inflate(R.menu.options_menu, menu);
                Log.v(this.toString(), "Done inflating menu.");
                return true;
            }

            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                Log.v(this.toString(), "An item was clicked.");
                switch(item.getItemId()) {
                case R.id.dictLookup:
                    Log.v(this.toString(), "Look up dictionary.");
                    break;

                case R.id.readFromHere:
                    Log.v(this.toString(), "Start reading from here:" + ed.getSelectionStart());
                }
                return false;
            }
        };
    }
}

My question(s):
1. How do I override the default behavior of the TextView?
2. How do I get text selection with contextual action menu?

War es hilfreich?

Lösung

if you want to get custom contextual action mode on text selection, then you can do somehing like this

    ed = (TextView) findViewById(R.id.txtview);
    ed.setText("Hello World! Let's select some text!!");
    initActionModeCallbacks();
    ed.setTextIsSelectable(true);
    ed.setCustomSelectionActionModeCallback(mActionModeCallback);

    ed.setOnLongClickListener(new View.OnLongClickListener() {

        @Override
        public boolean onLongClick(View v) {
            Log.v(this.toString(), "Long click.");
            ed.setCursorVisible(true);
            v.setSelected(true);

            return false;
        }
    });

and in onCreateActionMode(ActionMode mode, Menu menu), if you want to remove standard selection items, you can call

menu.clear();

also note, items in your menu needs to have SHOW_AS_ACTION_ALWAYS flag, because overflow button is not working cause focus change https://stackoverflow.com/a/9883763/2751697

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top