TextView 仿WPS搜索关键字标红查看可显示当前位置

博客介绍了如何在TextView中实现类似WPS的全文搜索功能,包括关键字标红、显示当前位置,以及通过按钮实现快速跳转到下一个搜索结果。内容涉及查找内容在文本中的下标计算、字符位置管理、坐标计算以及布局文件的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TextView 中文本内容过长,需要快速定位到某关键字时,类似于WPS全文查找搜索内容,并且可以进行定位到搜索内容进行显示,也可点击按钮,跳转到下一处搜索内容处。
TextView进行关键字匹配,需要找到该查找内容在文本中的下标

    private List<Integer> position;//全文中查找内容的所有位置
    private int subPos = 0;
    /**
     * 获取查找文字下标
     * @param str   文本内容
     * @param inputs    查找内容
     * @param resStr    重新拼装的文本内容
     * @return
     */
    public StringBuffer getSreachPosition(String str, String inputs, StringBuffer resStr) {
        int index = str.length();//用来做为标识,判断关键字的下标  
        int theIndex = str.indexOf(inputs);
        if (theIndex < index && theIndex > 0) {
            index = theIndex;//替换下标  
        }
        //如果条件成立,表示串中已经没有可以被替换的关键字,否则递归处理  
        if (index == str.length()) {
            resStr.append(str);
        } else {
            resStr.append(str.substring(0, index));
            resStr.append("<font color='#FF0000'>" + str.substring(index, index + inputs.length()) + "</font>");
            position.add(index + inputs.length() + subPos);
            subPos += (index + inputs.length());
            String str1 = str.substring(index + inputs.length(), str.length());
            addChild(str1, inputs, resStr);//剩余的字符串继续替换  
        }
        return resStr;
    }

获取到在TextView文本中的查找内容的所有位置后,通过这些位置获取相应的Y轴坐标,在TextView是通过Layout来管理字符的位置

private List<Integer> meau;// y 坐标集合
    /**
     * 获取每一个下标对应的 y 坐标
     * @param position
     */
    public void getLine(List<Integer> position) {
        Layout layout = textview.getLayout();
        int yAxisBottom = 0;
        for (int j = 0; j < position.size(); j++) {
            Rect bound = new Rect();
            int line = layout.getLineForOffset(position.get(j));
            layout.getLineBounds(line, bound);
            if (yAxisBottom != bound.bottom + textview.getScrollY()) {
                yAxisBottom = bound.bottom + textview.getScrollY();
                //这里设置 y-100 是由于查找内容显示到了屏幕最顶端,视觉效果不佳
                if (yAxisBottom > 100) {
                    meau.add(yAxisBottom - 100);
                }
            }
        }
    }

TextView.getScrollY()获取textview展示的内容最上面一行的坐标,这样的话我们就可以算出当前字符串的在屏幕上的坐标位置。
然后在TextView上显示出

/**
 * @param content 显示在TextView中的全文内容
 */
public void showContentSreach(String content) {
        String input = edittext.getText().toString();
        if (input.equals("")) {
            ToastUtils.showToast(LawDetailsActivity.this, "查找内容不能为空!");
        } else {
                StringBuffer resStr = new StringBuffer();
                position = new ArrayList<>();
                meau = new ArrayList<>();
                subPos = 0;
                String text = getSreachPosition(content, input, resStr).toString();
                content.setText(Html.fromHtml(text));
                if (null != position && position.size() > 0) {
                    getLine(position);
                    pos = 0;
                    scrollview.scrollTo(0, meau.get(pos));
                }
        }
    }

接下来就是点击按钮可以快速定位到下一个地方

    private int pos = 0; //记录点击次数
    @OnClick({R.id.syg, R.id.xyg})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.syg:
                if (null != meau && meau.size() > 0) {
                    if (pos == 0){
                        ToastUtils.showToast(this, "已到到顶了");
                    } else {
                        pos --;
                        scrollview.scrollTo(0, meau.get(pos));
                    }
                }
                break;
            case R.id.xyg:
                if (null != meau && meau.size() > 0) {
                    if (pos == meau.size()){
                        ToastUtils.showToast(this, "已到到底了");
                    } else {
                        scrollview.scrollTo(0, meau.get(pos));
                        pos ++;
                    }
                }
                break;
        }
    }

最后贴上我的布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/white">
    <ScrollerView
        android:id="@+id/scrollview"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:padding="10dp">

            <TextView
                android:id="@+id/content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="15sp"
                android:textColor="@color/black_text01"
                android:layout_marginBottom="10dp"/>

        </LinearLayout>

    </ScrollerView>

    <LinearLayout
        android:id="@+id/sreach_linear"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center_vertical"
        android:background="#50000000"
        android:padding="7dp"
        android:layout_below="@+id/title_layout">

        <EditText
            android:id="@+id/edit_content"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@drawable/edit_background"
            android:textColor="@color/text_color"
            android:textSize="17sp"
            android:padding="7dp"/>

        <Button
            android:id="@+id/query"
            android:layout_width="60dp"
            android:layout_height="@dimen/dp_35"
            android:background="@drawable/ic_button_blue"
            android:layout_marginLeft="10dp"
            android:text="查找"
            android:textColor="@color/white"
            android:textSize="@dimen/sp_17"/>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/sreach_tools"
        android:layout_width="match_parent"
        android:layout_height="35dp"
        android:orientation="horizontal"
        android:gravity="center"
        android:layout_margin="30dp"
        android:layout_alignParentBottom="true"
        android:background="@drawable/text_style_02">

        <ImageView
            android:id="@+id/syg"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:gravity="center"
            android:src="@drawable/syg"/>
        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:background="#b9b9b9"/>
        <ImageView
            android:id="@+id/xyg"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:gravity="center"
            android:src="@drawable/xyg"/>
    </LinearLayout>
</RelativeLayout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值