在应用程序暂停后,可滚动TextView不允许选择文本

时间:2018-10-11 20:57:05

标签: android android-layout textview

我有一个可滚动的TextView,用户可以在其中选择文本。我通过将移动方法设置为ScrollingMovementMethod来添加滚动条。

问题:除非应用程序已暂停(例如,在切换应用程序之后),否则选择效果很好。一旦该应用程序处于活动状态,选择将停止工作,并且我在日志中收到以下消息:

  

W / TextView:TextView不支持文本选择。选拔   已取消。

我的设置:

我有一个CoordinatorLayout的活动和一个TextView包裹在RelativeLayout中的片段,如下所示:

<TextView
    android:id="@+id/text_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentStart="true"
    android:scrollbars="vertical" />

在Java代码中,我必须这样做:

textView.setMovementMethod(new ScrollingMovementMethod());
textView.setTextIsSelectable(true);
textView.setFocusable(true);
textView.setFocusableInTouchMode(true);

因为这是根据thisthisthis问题解决的唯一方法。

编辑:

问题出在以下电话中

textView.setMovementMethod(new ScrollingMovementMethod());

如果我删除它,它可以工作,但是我不明白为什么。

重现此问题的最少步骤:

1)使用以下布局用TextView创建一个空的Activity。

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/text_view"
        android:text="Some very very very long text..."
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:scrollbars="vertical" />

</android.support.design.widget.CoordinatorLayout>

2)用TextView方法设置onStart()的可见性参数。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        TextView textView = findViewById(R.id.text_view);
        textView.setMovementMethod(new ScrollingMovementMethod());
        textView.setTextIsSelectable(true);
        textView.setFocusable(true);
        textView.setFocusableInTouchMode(true);
    }
}

3)在暂停应用程序之前和之后,尝试使用TextView上的上下文菜单。

编辑2:

删除setMovementMethod(new ScrollingMovementMethod())解决了我的问题,此后功能正常运行。但是我不确定为什么要添加它,而且如果删除它,恐怕它会刹车。任何人可能会结合使用ScrollingMovementMethodandroid:scrollbars="vertical"的想法。可能在某些情况下xml无法正常工作?有想法吗?而且我仍然很感兴趣,为什么使用ScrollingMovementMethod刹车选择功能?

4 个答案:

答案 0 :(得分:3)

请从您的XML中替换以下代码。

<TextView
    android:id="@+id/text_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentStart="true"
    android:enabled="true"
    android:textIsSelectable="true"
    android:focusable="true"
    android:longClickable="true" 
    android:scrollbars="vertical" />

从程序中删除以下代码:

textView.setTextIsSelectable(true);
textView.setFocusable(true);
textView.setFocusableInTouchMode(true);

setTextIsSelectable()方法的内部代码:

public void setTextIsSelectable(boolean selectable) {
        if (!selectable && mEditor == null) return; // false is default value with no edit data

        createEditorIfNeeded();
        if (mEditor.mTextIsSelectable == selectable) return;

        mEditor.mTextIsSelectable = selectable;
        setFocusableInTouchMode(selectable);
        setFocusable(FOCUSABLE_AUTO);
        setClickable(selectable);
        setLongClickable(selectable);

        // mInputType should already be EditorInfo.TYPE_NULL and mInput should be null

        setMovementMethod(selectable ? ArrowKeyMovementMethod.getInstance() : null);
        setText(mText, selectable ? BufferType.SPANNABLE : BufferType.NORMAL);

        // Called by setText above, but safer in case of future code changes
        mEditor.prepareCursorControllers();
    }

以编程方式,他们也在做我在XML中提到的相同的事情。因此,根据您的要求,我们可以使用它。

答案 1 :(得分:2)

我有非常相似的问题; texview可以滚动但不能选择。

从您的代码中删除此代码:

texview.setMovementMethod(new ScrollingMovementMethod())

我将这些添加到xml的textview中

android:scrollHorizontally="true" android:textIsSelectable="true"

答案 2 :(得分:1)

设置ScrollingMovementMethod使TextView能够“自主”滚动,例如当您设置很长的文本时,该文本会在底部或边缘被切掉。使用ScrollingMovementMethod,您可以滚动TextView,而无需将其放置在可滚动容器中,例如在ScrollViewHorizontalScrollView

android:scrollbars="vertical"行表示,如果此View获得“可滚动性”(例如,通过上述移动方法),则UI应该仅显示vertical滚动条。来自文档:

  

定义在滚动时是否显示滚动条。

它是View文档,而不是TextView文档,因为View的扩展“种类”很少能获得“可收藏性”,包括所有ViewGroup这样的{ {1}},ScrollViewListView

最后这行代码在您的代码中做什么?在setTextIsSelectable内,您有以下一行:

RecyclerView

因此,实际上,它的重写运动方法是在您自己的代码中设置了几行。我敢打赌,前段时间您的setMovementMethod(selectable ? ArrowKeyMovementMethod.getInstance() : null); 是“可独立的”,而有一天,一些聪明的人重写了此内容,并将TextView放在了其中。 XML中的TextView和移动方法保留在代码中。

ScrollView一直工作到textIsSelectable暂停,因为恢复后,您(再次)设置了Activity,但是在ScrollableMovementMethod内,您已经

setTextIsSelectable

您在 if (mEditor.mTextIsSelectable == selectable) return; 暂停之前的第一次运行中设置了mTextIsSelectable标志,并且此标志被恢复,因此下面的代码不会被触发(因此移动方法不会用{{ 1}}和您的Activity停留)。因此,请回答以下问题:此行在您的代码中的作用:在暂停并恢复ArrowKeyMovementMethod之后,它打破了“选择能力”,除此之外没有其他

来自ScrollingMovementMethodArrowKeyMovementMethod

笔记:仅在ScrollableMovementMethod(如上所述,在Activity内部设置为移动方法)中,您才覆盖了ArrowKeyMovementMethod方法和里面有一些行处理选择

编辑:还请注意,在setTextIsSelectable内设置了“可聚焦性”,因此这些行是不必要的:

onTouchEvent

因此您可以将代码缩短为仅一行:

setTextIsSelectable

或删除所有引用的Java代码并添加一个XML行:

textView.setFocusable(true);
textView.setFocusableInTouchMode(true);

答案 3 :(得分:0)

您可以通过两种方式选择TextView

通过XML:

 android:textIsSelectable="true"

通过Java代码:

 textView.setTextIsSelectable(true);