如何在 TextView 中选择文本时覆盖 "Copy"、"Share" 和 "Select All" 选项
How to override "Copy", "Share" and "Select All" options while selecting a text in a TextView
我有一个 TextView
用户可以在其中 select 文本。默认情况下会出现以下选项:"Copy"、"Share" 和 "Select All"。
我需要用自定义选项覆盖它们。但我找不到该怎么做。我浏览了文档和 this nice article 但不乏。这篇文章解释了当用户按下三点按钮时如何扩展菜单,这不是我需要的。
问题:如何覆盖文本部分菜单中的默认 "Copy"、"Share" 和 "Select All" 选项?
这是我的视图:
<TextView
android:id="@+id/transcript"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
在 java 代码中我有:
transcript.setTextIsSelectable(true);
transcript.setFocusable(true);
transcript.setFocusableInTouchMode(true);
您可以使用 TextView.setCustomSelectionActionModeCallback()
来执行此操作。
我整理了一个非常简单的应用程序来演示如何使用此功能。
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView text = (TextView) findViewById(R.id.text);
CustomActionModeCallback callback = new CustomActionModeCallback(this);
text.setCustomSelectionActionModeCallback(callback);
}
}
activity_main.xml
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
android:text="@string/lorem_ipsum"
android:textIsSelectable="true"/>
</FrameLayout>
CustomActionModeCallback.java
public class CustomActionModeCallback implements ActionMode.Callback {
private final Context context;
public CustomActionModeCallback(Context context) {
this.context = context;
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
menu.clear();
mode.getMenuInflater().inflate(R.menu.menu_custom, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item.getItemId() == R.id.custom_one) {
Toast.makeText(context, "One!", Toast.LENGTH_SHORT).show();
mode.finish();
return true;
}
else if (item.getItemId() == R.id.custom_two) {
Toast.makeText(context, "Two!", Toast.LENGTH_SHORT).show();
mode.finish();
return true;
}
else if (item.getItemId() == R.id.custom_three) {
Toast.makeText(context, "Three!", Toast.LENGTH_SHORT).show();
mode.finish();
return true;
}
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
}
menu_custom.xml
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/custom_one"
android:title="One"
app:showAsAction="never"/>
<item
android:id="@+id/custom_two"
android:title="Two"
app:showAsAction="never"/>
<item
android:id="@+id/custom_three"
android:title="Three"
app:showAsAction="never"/>
</menu>
MainActivity
或 xml 文件中没有什么可评论的。所有的魔法都发生在 CustomActionModeCallback
.
onCreateActionMode()
和 onPrepareActionMode()
都可用于将自定义菜单项添加到菜单中。如果您使用onCreateActionMode()
,系统会在溢出菜单中添加一些额外的选项,例如:
如果您使用onPrepareActionMode()
,则不会添加额外的项目。
注意无论如何都要return true
from onCreateActionMode()
(返回false会导致菜单不显示),但是你只需要return true
from onPrepareActionMode()
如果你真的修改了菜单。
您可以在 onActionItemClicked()
中处理用户对自定义项目的点击。在我的示例中,我只是显示 Toast
,然后关闭上下文菜单(使用 ActionMode.finish()
)。在这种方法中,您应该 return true
仅在您自己处理的菜单项上;返回 false 允许系统默认操作发生(例如,如果您想让用户选择 select 所有文本)。
最后,当菜单关闭时调用onDestroyActionMode()
。也许你对此有一些用处;我没有。
我有一个 TextView
用户可以在其中 select 文本。默认情况下会出现以下选项:"Copy"、"Share" 和 "Select All"。
我需要用自定义选项覆盖它们。但我找不到该怎么做。我浏览了文档和 this nice article 但不乏。这篇文章解释了当用户按下三点按钮时如何扩展菜单,这不是我需要的。
问题:如何覆盖文本部分菜单中的默认 "Copy"、"Share" 和 "Select All" 选项?
这是我的视图:
<TextView
android:id="@+id/transcript"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
在 java 代码中我有:
transcript.setTextIsSelectable(true);
transcript.setFocusable(true);
transcript.setFocusableInTouchMode(true);
您可以使用 TextView.setCustomSelectionActionModeCallback()
来执行此操作。
我整理了一个非常简单的应用程序来演示如何使用此功能。
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView text = (TextView) findViewById(R.id.text);
CustomActionModeCallback callback = new CustomActionModeCallback(this);
text.setCustomSelectionActionModeCallback(callback);
}
}
activity_main.xml
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
android:text="@string/lorem_ipsum"
android:textIsSelectable="true"/>
</FrameLayout>
CustomActionModeCallback.java
public class CustomActionModeCallback implements ActionMode.Callback {
private final Context context;
public CustomActionModeCallback(Context context) {
this.context = context;
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
menu.clear();
mode.getMenuInflater().inflate(R.menu.menu_custom, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item.getItemId() == R.id.custom_one) {
Toast.makeText(context, "One!", Toast.LENGTH_SHORT).show();
mode.finish();
return true;
}
else if (item.getItemId() == R.id.custom_two) {
Toast.makeText(context, "Two!", Toast.LENGTH_SHORT).show();
mode.finish();
return true;
}
else if (item.getItemId() == R.id.custom_three) {
Toast.makeText(context, "Three!", Toast.LENGTH_SHORT).show();
mode.finish();
return true;
}
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
}
menu_custom.xml
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/custom_one"
android:title="One"
app:showAsAction="never"/>
<item
android:id="@+id/custom_two"
android:title="Two"
app:showAsAction="never"/>
<item
android:id="@+id/custom_three"
android:title="Three"
app:showAsAction="never"/>
</menu>
MainActivity
或 xml 文件中没有什么可评论的。所有的魔法都发生在 CustomActionModeCallback
.
onCreateActionMode()
和 onPrepareActionMode()
都可用于将自定义菜单项添加到菜单中。如果您使用onCreateActionMode()
,系统会在溢出菜单中添加一些额外的选项,例如:
如果您使用onPrepareActionMode()
,则不会添加额外的项目。
注意无论如何都要return true
from onCreateActionMode()
(返回false会导致菜单不显示),但是你只需要return true
from onPrepareActionMode()
如果你真的修改了菜单。
您可以在 onActionItemClicked()
中处理用户对自定义项目的点击。在我的示例中,我只是显示 Toast
,然后关闭上下文菜单(使用 ActionMode.finish()
)。在这种方法中,您应该 return true
仅在您自己处理的菜单项上;返回 false 允许系统默认操作发生(例如,如果您想让用户选择 select 所有文本)。
最后,当菜单关闭时调用onDestroyActionMode()
。也许你对此有一些用处;我没有。