12/08/2018, 15:04

Search and highlight text in android

Trong bài viết này mình sẽ hướng dẫn các bạn tạo highlight text khi tìm kiếm như hình sau: Đầu tiên, các bạn tạo 1 layout activity_main.xml cơ bản gồm 1 EditText và 1 TextView như sau: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/a ...

Trong bài viết này mình sẽ hướng dẫn các bạn tạo highlight text khi tìm kiếm như hình sau: Đầu tiên, các bạn tạo 1 layout activity_main.xml cơ bản gồm 1 EditText và 1 TextView như sau:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_awidth="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.framgia.myapplication.MainActivity"
    android:orientation="vertical"
    >
    <EditText
        android:id="@+id/search_edt"
        android:layout_awidth="match_parent"
        android:layout_height="wrap_content"
        />
    <TextView
        android:id="@+id/tv"
        android:layout_awidth="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/long_text"
        />
</LinearLayout>

Nội dung file strings.xml:

<resources>
    <string name="app_name">My Application</string>
    <string name="long_text">This is a quick tutorial on how to highlight all the occurrences of a keyword provided by the user during a search.  We will use SpannableString to achieve this.  First set up a basic layout with a EditText and a TextView. Below is the XML for the same.</string>
</resources>

Tiếp theo chúng ta sẽ ánh xạ các view trên MainActivity.java

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mEditText = (EditText) findViewById(R.id.search_edt);
        mTextView = (TextView) findViewById(R.id.tv);
    }

Tiếp theo thêm TextWatcher cho EditText:

mEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                highlightText(s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

Bây giờ đến hàm quan trọng nhất, là hàm highlightText(String s)

private void highlightText(String s) {
        SpannableString spannableString = new SpannableString(mTextView.getText());
        BackgroundColorSpan[] backgroundColorSpan =
                spannableString.getSpans(0, spannableString.length(), BackgroundColorSpan.class);
        for (BackgroundColorSpan bgSpan : backgroundColorSpan) {
            spannableString.removeSpan(bgSpan);
        }
        int indexOfKeyWord = spannableString.toString().indexOf(s);
        while (indexOfKeyWord > 0) {
            spannableString.setSpan(new BackgroundColorSpan(Color.YELLOW), indexOfKeyWord,
                    indexOfKeyWord + s.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            indexOfKeyWord = spannableString.toString().indexOf(s, indexOfKeyWord + s.length());       
        }
        mTextView.setText(spannableString);
    }

Sau đây mình xin giải thích ý nghĩa của hàm này như sau:

  • Phần chính của hàm này chính là sử dụng SpannableString.
  • Đầu tiên chúng ta lấy kí tự mà chúng ta nhập và từ bàn phím
  • Sau đó tạo 1 SpannableString từ nội dung của TextView
  • Chú ý rằng, mình sẽ xóa các highlight từ tìm kiếm trước đó của người dùng bằng cách dùng vòng lặp trên mảng BackgroundColorSpan và loại bỏ từng cái một bằng hàm .removeSpan trên spannableString
  • indexOfKeyWord = spannableString.toString().indexOf(s); giúp chúng ta tìm được vị trí đầu tiên của keyword
  • Sau đó trong vòng lặp while chúng ta sẽ tạo background mới cho String Bây giờ khi chạy app bạn sẽ được sản phẩm như hình vẽ
0