Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

textView.getSelectionEnd() returning start index value on Samsung Marshmallow 6.0 devices

This issue is observed on Samsung devices with Android 6.0 only. It is working fine on all other devices, including non - Samsung devices with android 6.0 and Samsung devices with Android 5.1 and below.

Currently we don`t have any Samsung device with Android 6.0 to readily check things on it, but we are arranging it soon.


The feature where we are using this :

The user long presses on a word from a sentence in a TextView and then user can edit the selected word.


We accomplish this by :

  • Making the TextView selectable and adding a LongClickListener.
  • Adding a custom Selection Action Mode CallBack and overriding onCreateActionMode() to return false, since we don`t need the default cut-copy-paste action mode.
  • Handling the onLongClickListener to get the exact selected word and provide a UI to correct and replace the word.

The issue we are facing :

textView.getSelectionStart() returns the correct start index but textView.getSelectionEnd() returns the value of start index instead of end index. We have a guard condition that whenever start and end index are same then the selection is for a space and hence we ignore it, thus all the word selections on Samsung devices with Android 6.0 and up are ignored resulting into the feature failure.


Things we tried :

  • We tried replacing the ActionMode.Callback with ActionMode.Callback2 as mentioned under "Text Selection" section on page Android 6.0 Changes but it didn`t help in fixing this issue.
  • Tried searching for any extra samsung setting available related to text selection, clipboard etc but no luck. I know this can be a lame option but i do not take chances with Samsung Touchwiz. I did found a setting to alter the delay for touch selection ranging from 0.5 to 2.0 seconds.

The code snippets :

tvText.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            return false; // 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) {
        }
    });

    tvText.setOnLongClickListener(new View.OnLongClickListener() { 

        @Override
        public boolean onLongClick(View v) {

            final TextView textView = (TextView) v;
            new Handler().postDelayed(new Runnable() {

                @Override
                public void run() {

                    //This works correct on all devices with Android 6.0
                    int startIndex = textView.getSelectionStart();

                    //This works wrong on Samsung devices with Android 6.0, result is same as getSelectionStart()
                    int endIndex = textView.getSelectionEnd();

                    //The guard condition where we ignore the empty selections
                    if ((endIndex - startIndex) <= 0) {
                        return;
                    }

                    // Do bunch of things to UI like applying some different foreground colors to the selected word, striking out selected word etc.
                }
            }, TEXT_LONG_PRESS_DELAY);
            return false;
        }
    }); 

The xml code for the TextView and it`s style :

<TextView
    android:id="@+id/tvText"
    style="@style/StyleChatBubbleText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="2dp"/>

<style name="StyleChatBubbleText">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:textSize">16dp</item>
    <item name="android:textColor">@color/text_black</item>
    <item name="android:textIsSelectable">true</item>
    <item name="typeface">roboto_regular</item>


Any help regarding this issue is appreciated.

like image 229
binaryKarmic Avatar asked May 25 '16 06:05

binaryKarmic


2 Answers

check build version if buildversion is >= 6 return true , implement a floating toolbar with your custom layout. if buildversion <6 return false, use your current implementation

like image 175
NIPHIN Avatar answered Nov 15 '22 19:11

NIPHIN


Better late than never, but I encountered this exact same problem on a Samsung Galaxy S5 running Marshmallow (23).

I originally used the simple methods to get the selection bounds:

int selectionStart = mEditText.getSelectionStart();
int selectionEnd = mEditText.getSelectionEnd();

This is fine on most devices and also on Android Studio emulator running Marshmallow, but on the Galaxy S5 both returned values are always identical and return the selection end position.

The solution I found was to access the EditText's internal selection directly, so the following gives the correct selection end position for all versions of Android on all devices I have tested.

int selectionStart = mEditText.getEditableText().getSpanEnd(Selection.SELECTION_START);
int selectionEnd = mEditText.getEditableText().getSpanEnd(Selection.SELECTION_END);

It may be worth noting that the selection start position may be higher than the end position (e.g. if the selection was created by selecting and dragging towards the start of the edit text).

like image 20
AGDownie Avatar answered Nov 15 '22 19:11

AGDownie