应用程序暂停后,可滚动的 TextView 不允许 select 文本
Scrollable TextView doesn't allow to select text after the application is paused
我有一个可滚动的 TextView
,用户可以在其中 select 文本。我通过将移动方法设置为 ScrollingMovementMethod
.
来添加滚动条
问题:除非应用程序暂停(例如,切换应用程序后),否则选择工作正常。应用程序再次激活后 selection 停止工作,我在日志中收到以下消息:
W/TextView: TextView does not support text selection. Selection
cancelled.
我的设置:
我有一个 Activity 和 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 and 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) 在onStart()
方法中设置TextView
的可见性参数。
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
刹车 selection 功能感兴趣?
请替换您 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 中提到的同样的事情。因此,根据您的要求,我们可以使用它。
您可以通过两种方式使 TextView 可选择
至XML:
android:textIsSelectable="true"
通过Java代码:
textView.setTextIsSelectable(true);
设置 ScrollingMovementMethod
使 TextView
能够滚动 "by own",例如当您设置非常长的文本并且它在底部或边缘被切割时。使用 ScrollingMovementMethod
你可以滚动 TextView
,不需要将它放在可滚动的容器中,例如在 ScrollView
或 HorizontalScrollView
android:scrollbars="vertical"
行表示,如果此 View
得到 "scrollablility"(例如通过上述移动方法),则 UI 应该仅显示 vertical
滚动条。来自文档:
Defines which scrollbars should be displayed on scrolling or not.
并且它是 View
文档,而不是 TextView
特别是,因为很少有扩展 "kinds" of View
s 可以获得 "scolllability",包括所有 ViewGroup
如ScrollView
、ListView
、RecyclerView
等
最后,这一行在您的代码中做了什么?在 setTextIsSelectable
里面你有这一行:
setMovementMethod(selectable ? ArrowKeyMovementMethod.getInstance() : null);
所以实际上它的覆盖移动方法是您在自己的代码中设置上面的几行。我敢打赌,不久前你的 TextView
是 scollable "by itself" 并且有一天一些聪明的人重写了它并将 TextView
放在例如ScrollView
在XML,移动方法留在代码中。
textIsSelectable
一直工作到 Activity
暂停,因为在恢复后你(再次)设置了 ScrollableMovementMethod
,但在 setTextIsSelectable
里面你有
if (mEditor.mTextIsSelectable == selectable) return;
你在 Activity
暂停前的第一个 运行 设置了 mTextIsSelectable
标志,并且这个标志被恢复,所以下面的代码没有被触发(所以移动方法不是使用 ArrowKeyMovementMethod
重新设置,您的 ScrollableMovementMethod
保持不变)。因此,请回答此行在您的代码中的作用:它在暂停和恢复 Activity
后中断 "selectionability",除此之外什么都没有
来自 ScrollingMovementMethod
and ArrowKeyMovementMethod
来源的注释:仅在 ArrowKeyMovementMethod
中(像上面那样在 setTextIsSelectable
中设置为移动方法)你已经覆盖了 onTouchEvent
方法并在其中一些行处理选择
编辑:另请注意,在 setTextIsSelectable
中您有设置 "focusability",因此这些行是不必要的:
textView.setFocusable(true);
textView.setFocusableInTouchMode(true);
因此您可以将代码缩短为一行:
textView.setTextIsSelectable(true);
或删除所有引用的 Java 代码并添加一个 XML 行:
android:textIsSelectable="true"
我遇到了非常相似的问题; texview 可以滚动但不能选择。
从您的代码中删除:
texview.setMovementMethod(new ScrollingMovementMethod())
我将这些添加到 xml 中的文本视图中:
android:scrollHorizontally="true"
android:textIsSelectable="true"
我有一个可滚动的 TextView
,用户可以在其中 select 文本。我通过将移动方法设置为 ScrollingMovementMethod
.
问题:除非应用程序暂停(例如,切换应用程序后),否则选择工作正常。应用程序再次激活后 selection 停止工作,我在日志中收到以下消息:
W/TextView: TextView does not support text selection. Selection cancelled.
我的设置:
我有一个 Activity 和 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 and 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) 在onStart()
方法中设置TextView
的可见性参数。
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
刹车 selection 功能感兴趣?
请替换您 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 中提到的同样的事情。因此,根据您的要求,我们可以使用它。
您可以通过两种方式使 TextView 可选择
至XML:
android:textIsSelectable="true"
通过Java代码:
textView.setTextIsSelectable(true);
设置 ScrollingMovementMethod
使 TextView
能够滚动 "by own",例如当您设置非常长的文本并且它在底部或边缘被切割时。使用 ScrollingMovementMethod
你可以滚动 TextView
,不需要将它放在可滚动的容器中,例如在 ScrollView
或 HorizontalScrollView
android:scrollbars="vertical"
行表示,如果此 View
得到 "scrollablility"(例如通过上述移动方法),则 UI 应该仅显示 vertical
滚动条。来自文档:
Defines which scrollbars should be displayed on scrolling or not.
并且它是 View
文档,而不是 TextView
特别是,因为很少有扩展 "kinds" of View
s 可以获得 "scolllability",包括所有 ViewGroup
如ScrollView
、ListView
、RecyclerView
等
最后,这一行在您的代码中做了什么?在 setTextIsSelectable
里面你有这一行:
setMovementMethod(selectable ? ArrowKeyMovementMethod.getInstance() : null);
所以实际上它的覆盖移动方法是您在自己的代码中设置上面的几行。我敢打赌,不久前你的 TextView
是 scollable "by itself" 并且有一天一些聪明的人重写了它并将 TextView
放在例如ScrollView
在XML,移动方法留在代码中。
textIsSelectable
一直工作到 Activity
暂停,因为在恢复后你(再次)设置了 ScrollableMovementMethod
,但在 setTextIsSelectable
里面你有
if (mEditor.mTextIsSelectable == selectable) return;
你在 Activity
暂停前的第一个 运行 设置了 mTextIsSelectable
标志,并且这个标志被恢复,所以下面的代码没有被触发(所以移动方法不是使用 ArrowKeyMovementMethod
重新设置,您的 ScrollableMovementMethod
保持不变)。因此,请回答此行在您的代码中的作用:它在暂停和恢复 Activity
后中断 "selectionability",除此之外什么都没有
来自 ScrollingMovementMethod
and ArrowKeyMovementMethod
来源的注释:仅在 ArrowKeyMovementMethod
中(像上面那样在 setTextIsSelectable
中设置为移动方法)你已经覆盖了 onTouchEvent
方法并在其中一些行处理选择
编辑:另请注意,在 setTextIsSelectable
中您有设置 "focusability",因此这些行是不必要的:
textView.setFocusable(true);
textView.setFocusableInTouchMode(true);
因此您可以将代码缩短为一行:
textView.setTextIsSelectable(true);
或删除所有引用的 Java 代码并添加一个 XML 行:
android:textIsSelectable="true"
我遇到了非常相似的问题; texview 可以滚动但不能选择。
从您的代码中删除:
texview.setMovementMethod(new ScrollingMovementMethod())
我将这些添加到 xml 中的文本视图中:
android:scrollHorizontally="true"
android:textIsSelectable="true"