【问题标题】:How to override "Copy", "Share" and "Select All" options while selecting a text in a TextView如何在 TextView 中选择文本时覆盖“复制”、“共享”和“全选”选项
【发布时间】:2018-10-11 16:15:05
【问题描述】:

我有一个TextView,用户可以在其中选择文本。默认情况下会出现以下选项:“复制”、“共享”和“全选”。 我需要用自定义选项覆盖它们。但我找不到如何做到这一点。我浏览了文档和this nice article,但也不乏。这篇文章解释了当用户按下三点按钮时如何扩展菜单,这不是我需要的。

问题:如何覆盖文本部分菜单中的默认“复制”、“共享”和“全选”选项?

这是我的视图:

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

【问题讨论】:

    标签: android android-layout textview android-menu


    【解决方案1】:

    您可以使用TextView.setCustomSelectionActionModeCallback() 来执行此操作。

    文档:https://developer.android.com/reference/android/widget/TextView.html#setCustomSelectionActionModeCallback(android.view.ActionMode.Callback)

    我整理了一个非常简单的应用程序来演示如何使用此功能。

    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(),则不会添加额外的项目。

    请注意,无论如何,您都必须从onCreateActionMode()return true(返回false 会导致菜单不显示),但如果您实际修改了菜单,则只需从onPrepareActionMode()return true

    您可以在onActionItemClicked() 中处理用户对您的自定义项目的点击。在我的示例中,我只是显示一个Toast,然后关闭上下文菜单(使用ActionMode.finish())。在这种方法中,您应该只在您自己处理的菜单项上return true;返回 false 允许发生系统默认操作(例如,如果您想为用户提供选择所有文本的选项)。

    最后,onDestroyActionMode() 在菜单关闭时被调用。也许你对此有一些用处;我没有。

    【讨论】:

    • 谢谢本!我什至没想到会有这么详细的答案。你正在为社区做伟大的工作。再次感谢(我还为您的其他一些优秀答案投票)。
    • 有没有办法使用 css/javascript 做到这一点?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 2012-08-02
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    • 2018-02-02
    相关资源
    最近更新 更多