有没有办法以编程方式在 TextView 中选择文本?

Posted

技术标签:

【中文标题】有没有办法以编程方式在 TextView 中选择文本?【英文标题】:Is there any way to programatically select text in a TextView? 【发布时间】:2014-06-18 06:26:08 【问题描述】:

我有一个TextView,我希望它允许用户搜索特定的字符串。如果找到该字符串,它应该突出显示。使用背景跨度太慢且尴尬,所以我想弄清楚是否可以让它选择字符串。我知道EditText 可以使用setSelection(),但我不希望用户能够编辑文本,同时仍然能够手动突出显示文本,我似乎无法管理一个EditText

我猜,那是非此即彼;是否可以或者以编程方式选择TextView 中的文本可以允许文本选择而不允许在EditText 中进行编辑?

注意:我实际上使用的是扩展TextView 的自定义视图,所以我假设它是扩展EditText;我只是不确定哪个(如果有的话)会起作用。

【问题讨论】:

可以更改部分 TextView 字符串的颜色。只需在部件周围使用一些 html 来标记并在 setText 中使用 HTML.fromHTML。或者你可以使用 Spannable 对象。 是的,我最初就是这样做的,但是因为文本很大,所以速度很慢。 “使用背景跨度太慢太尴尬”——嗯……真的吗?我没有看到这个问题。使用this sample project,我可以在大约20 行代码中在20-30 毫秒内搜索出现在较长字符串中的子字符串,删除所有现有的BackgroundColorSpans 并应用新的BackgroundColorSpans。 “文本很大”——有多大? 另外,文本选择本身将使用相同的BackgroundColorSpan 解决方案。 每页约 20,000 个字符。 【参考方案1】:

不确定问题是否仍然存在,我将提供我的解决方案。也许对来自搜索引擎的人有用。

因此,据我了解,目的是选择TextView 中的所有文本,而不能修改其内容。我没有检查它对非常大的文本有多有效,但希望不会那么糟糕。

请注意,API 版本应 >=11

import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.text.Selection;
import android.text.Spannable;
import android.util.AttributeSet;

public class SelectableTextView extends TextView

    public SelectableTextView(Context context)
    
        super(context);
        init();
    

    public SelectableTextView(Context context, AttributeSet attrs)
    
        super(context, attrs);
        init();
    

    public SelectableTextView(Context context, AttributeSet attrs, int defStyleAttr)
    
        super(context, attrs, defStyleAttr);
        init();
    

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public SelectableTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
    
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    

    private void init()
    
        if (Build.VERSION.SDK_INT > 10)
            setTextIsSelectable(true);
    

    @Override
    public boolean onTextContextMenuItem(int id)
    
        switch (id)
        
            case android.R.id.cut:
                return true;

            case android.R.id.paste:
                return true;

            case android.R.id.shareText:
            
                String selectedText = getText().toString().substring(getSelectionStart(), getSelectionEnd());

                if (selectedText != null && !selectedText.isEmpty())
                
                    Intent sendIntent = new Intent();
                    sendIntent.setAction(Intent.ACTION_SEND);
                    sendIntent.putExtra(Intent.EXTRA_TEXT, selectedText);
                    sendIntent.setType("text/plain");
                    sendIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    getContext().startActivity(sendIntent);
                

                return true;
            

            case android.R.id.selectAll:
            
                selectAllText();
                return true;
            
        

        return super.onTextContextMenuItem(id);
    

    public void selectAllText()
    
        if (Build.VERSION.SDK_INT > 10)
            Selection.setSelection((Spannable) getText(), 0, length());
    

【讨论】:

以上是关于有没有办法以编程方式在 TextView 中选择文本?的主要内容,如果未能解决你的问题,请参考以下文章

Android - 以编程方式设置 TextView TextStyle?

有没有办法在多 GPU 环境中以编程方式选择渲染 GPU? (视窗)

在 IE 8 中以编程方式选择文本区域中的文本

以编程方式单击时突出显示 TextView

以编程方式调整TextView的大小

以编程方式设置 TextView 的样式