textView.getSelectionEnd()返回Samsung Marshmallow 6.0设备上的起始索引值

时间:2016-05-25 06:47:48

标签: android android-6.0-marshmallow samsung-mobile

仅在使用Android 6.0的Samsung设备上观察到此问题。它在所有其他设备上运行良好,包括非三星设备与Android 6.0和三星设备与Android 5.1及以下。

目前我们没有任何配备Android 6.0的三星设备可以随时查看,但我们很快就会对其进行整理。

我们使用此功能:

用户长按TextView中句子中的单词,然后用户可以编辑所选单词。

我们通过以下方式实现这一目标:

  • 使TextView可选并添加LongClickListener。
  • 添加自定义选择操作模式CallBack并覆盖onCreateActionMode()以返回false,因为我们不需要默认的剪切 - 复制 - 粘贴操作模式。
  • 处理onLongClickListener以获取确切选定的单词并提供用于更正和替换单词的UI。

我们面临的问题:

textView.getSelectionStart()返回正确的起始索引,但 textView.getSelectionEnd()返回起始索引而不是结束索引的值。我们有一个保护条件,即每当开始和结束索引相同时,选择是针对一个空格,因此我们忽略它,因此在安装了Android 6.0及更高版本的三星设备上的所有单词选择都会被忽略,导致功能失败。

我们尝试的事情:

  • 我们尝试用<替换 ActionMode.Callback ActionMode.Callback2 ,如&#34;文字选择&#34;第Android 6.0 Changes页的部分,但它没有帮助解决这个问题 问题。
  • 尝试搜索与文本选择,剪贴板等相关的任何额外的三星设置,但没有运气。我知道这可能是一个蹩脚的选择,但我没有机会与三星Touchwiz。我确实找到了一个设置来改变触摸选择的延迟,范围从0.5到2.0秒。

代码片段:

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

TextView的xml代码及其样式:

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

对此问题的任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:1)

检查构建版本 如果buildversion是&gt; = 6返回true,请使用自定义布局实现浮动工具栏。 如果buildversion&lt; 6返回false,请使用当前的实现

答案 1 :(得分:1)

迟到总比没有好,但是我在运行棉花糖(23)的三星Galaxy S5上遇到了同样的问题。

我最初使用简单的方法来获得选择范围:

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

这在大多数设备上以及运行棉花糖的Android Studio模拟器上都可以,但是在Galaxy S5上,两个返回值始终相同,并返回选择结束位置。

我找到的解决方案是直接访问EditText的内部选择,因此以下内容为我测试过的所有设备上所有版本的Android提供了正确的选择结束位置。

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

值得注意的是,选择的开始位置可能高于结束位置(例如,如果选择是通过选择并向编辑文本的开头拖动来创建的)。