我有一个可滚动的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);
因为这是根据this,this和this问题解决的唯一方法。
编辑:
问题出在以下电话中
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())
解决了我的问题,此后功能正常运行。但是我不确定为什么要添加它,而且如果删除它,恐怕它会刹车。任何人可能会结合使用ScrollingMovementMethod
和android:scrollbars="vertical"
的想法。可能在某些情况下xml无法正常工作?有想法吗?而且我仍然很感兴趣,为什么使用ScrollingMovementMethod
刹车选择功能?
答案 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
,而无需将其放置在可滚动容器中,例如在ScrollView
或HorizontalScrollView
android:scrollbars="vertical"
行表示,如果此View
获得“可滚动性”(例如,通过上述移动方法),则UI应该仅显示vertical
滚动条。来自文档:
定义在滚动时是否显示滚动条。
它是View
文档,而不是TextView
文档,因为View
的扩展“种类”很少能获得“可收藏性”,包括所有ViewGroup
这样的{ {1}},ScrollView
,ListView
等
最后这行代码在您的代码中做什么?在setTextIsSelectable
内,您有以下一行:
RecyclerView
因此,实际上,它的重写运动方法是在您自己的代码中设置了几行。我敢打赌,前段时间您的setMovementMethod(selectable ? ArrowKeyMovementMethod.getInstance() : null);
是“可独立的”,而有一天,一些聪明的人重写了此内容,并将TextView
放在了其中。 XML中的TextView
和移动方法保留在代码中。
ScrollView
一直工作到textIsSelectable
暂停,因为恢复后,您(再次)设置了Activity
,但是在ScrollableMovementMethod
内,您已经
setTextIsSelectable
您在 if (mEditor.mTextIsSelectable == selectable) return;
暂停之前的第一次运行中设置了mTextIsSelectable
标志,并且此标志被恢复,因此下面的代码不会被触发(因此移动方法不会用{{ 1}}和您的Activity
停留)。因此,请回答以下问题:此行在您的代码中的作用:在暂停并恢复ArrowKeyMovementMethod
之后,它打破了“选择能力”,除此之外没有其他
ScrollingMovementMethod
和ArrowKeyMovementMethod
的笔记:仅在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);