0

Is there an API to set the start and end selection (index) in textview so that it can call CustomSelectionActionMode?

According to documentation, the Selection class has a SetSelection function that takes 3 arguments: spannable, start and end. But how do I retrieve the Selection class from TextView class?

Community
  • 1
  • 1
Tek Mun
  • 97
  • 9

2 Answers2

0

Here is the answer,

https://stackoverflow.com/a/22833303/1177865

mTextView.setCustomSelectionActionModeCallback(new Callback() {

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        // Remove the "select all" option
        menu.removeItem(android.R.id.selectAll);
        // Remove the "cut" option
        menu.removeItem(android.R.id.cut);
        // Remove the "copy all" option
        menu.removeItem(android.R.id.copy);
        return true;
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        // Called when action mode is first created. The menu supplied
        // will be used to generate action buttons for the action mode

        // Here is an example MenuItem
        menu.add(0, DEFINITION, 0, "Definition").setIcon(R.drawable.ic_action_book);
        return true;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        // Called when an action mode is about to be exited and
        // destroyed
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        switch (item.getItemId()) {
            case DEFINITION:
                int min = 0;
                int max = mTextView.getText().length();
                if (mTextView.isFocused()) {
                    final int selStart = mTextView.getSelectionStart();
                    final int selEnd = mTextView.getSelectionEnd();

                    min = Math.max(0, Math.min(selStart, selEnd));
                    max = Math.max(0, Math.max(selStart, selEnd));
                }
                // Perform your definition lookup with the selected text
                final CharSequence selectedText = mTextView.getText().subSequence(min, max);
                // Finish and close the ActionMode
                mode.finish();
                return true;
            default:
                break;
        }
        return false;
    }

});
hjchin
  • 864
  • 2
  • 8
  • 25
  • I have added setCustomSelectionActionModeCallback. This part of the code is working initially until I added Touch listener. Apparently, with touch listener, long press no longer select the text. Hence, my question is how I can manually set the SelectionStart and SelectionEnd so that it will trigger CustomSelectionActionModeCallback. – Tek Mun Nov 16 '18 at 01:37
  • you override the touch listener and the control cannot flow as usual. Can you post your ontouch listener? I think the idea is to continue to pass the control to parent by using return false. https://developer.android.com/reference/android/view/View.OnTouchListener. Sample code https://stackoverflow.com/questions/11690504/how-to-use-view-ontouchlistener-instead-of-onclick – hjchin Nov 16 '18 at 05:50
0
bool LongPress()
{
    if (longpressed == 1)
    {
    int x = (int)downX;
    int y = (int)downY;
    x -= textview.PaddingLeft;
    y -= textview.PaddingTop;
    x += textview.ScrollX;
    y += textview.ScrollY;
    Android.Text.Layout layout = textview.Layout;
    int line = layout.GetLineForVertical(y);
    int off = layout.GetOffsetForHorizontal(line, x);
    var clickspans = ss.GetSpans(off, off, Java.Lang.Class.FromType(typeof(ClickableSpan)));
    if (clickspans.Count() > 0)
    {
        ClickableSpan clickspan = (ClickableSpan)clickspans[0];
        startselection = ss.GetSpanStart(clickspan);
        endselection = ss.GetSpanEnd(clickspan);
        /*
        This is where I intend to add Selection.SetSelection(ss, startselection, endselection);
        */
        //textview.StartActionMode(textview.CustomSelectionActionModeCallback, ActionModeType.Floating);
    }
    longpressed = 2;
    }
    return false;
}

private void TouchLabel(object sender, TouchEventArgs e)
{
    MotionEvent motionevt = e.Event;
    if (MotionEvent.ActionToString(motionevt.Action) == "ACTION_DOWN")
    {
    Device.StartTimer(TimeSpan.FromMilliseconds(500), LongPress);
    longpressed = 1;
    }
    else if (MotionEvent.ActionToString(motionevt.Action) == "ACTION_MOVE")
    {
    longpressed = 2;
    }
    else if ((MotionEvent.ActionToString(motionevt.Action) == "ACTION_UP") || (MotionEvent.ActionToString(motionevt.Action) == "ACTION_CANCEL"))
    {
    if (longpressed == 1)
    {
        longpressed = 2;
    }
    longpressed = 0;
    }
}

This is written in C# for Xamarin.Android. I am using timer to detect "LongPress" and would like to set the "selected/highlighted" inside the LongPress function.

Tek Mun
  • 97
  • 9