Android ListView 搜索关键字高亮显示

jopen 10年前

最近项目中用到 EditText + ListView + TextWatcher 实现关键字搜索功能,要求 ListView item 的 name 中如果包含了 关键字,则对其进行 高亮。研究了一下实现这个效果,主要是 用到 Html.fromHtml(source); 方法。

 

MainActivity.java

package com.example.highlight;    import java.util.ArrayList;  import java.util.List;    import com.example.android_highlightkeyword.R;    import android.os.Bundle;  import android.app.Activity;  import android.text.Editable;  import android.text.Html;  import android.text.Spanned;  import android.text.TextWatcher;  import android.view.Menu;  import android.view.View;  import android.view.ViewGroup;  import android.widget.BaseAdapter;  import android.widget.EditText;  import android.widget.ListView;  import android.widget.TextView;    public class MainActivity extends Activity {     private ListView mListView;   private EditText et_input;   private String userInput = "";   private List<Data> dataList = new ArrayList<Data>();   private char[] chs = { 'A', 'B', 'C', 'D', 'E', 'M', 'L', 'F', 'X', 'W',     'Z' };   private HightKeywordsAdapter mAdapter;     @Override   protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);      findViewById();    initListViewData();    setListener();   }     private void setListener() {      et_input.addTextChangedListener(watcher);      mAdapter = new HightKeywordsAdapter();      mListView.setAdapter(mAdapter);   }     private TextWatcher watcher = new TextWatcher() {      public void onTextChanged(CharSequence s, int start, int before,      int count) {       userInput = String.valueOf(s);       mAdapter.notifyDataSetChanged();      }      public void beforeTextChanged(CharSequence s, int start, int count,      int after) {      }      public void afterTextChanged(Editable s) {      }   };     private void initListViewData() {      for (char ch : chs) {       for (int i = 0; i < 5; i++) {        Data data = new Data(String.valueOf(ch) + "中国",        String.valueOf(ch) + i, String.valueOf(ch));        dataList.add(data);     }    }     }     private void findViewById() {    et_input = (EditText) findViewById(R.id.et_input);    mListView = (ListView) findViewById(R.id.mListView);   }     @Override   public boolean onCreateOptionsMenu(Menu menu) {    // Inflate the menu; this adds items to the action bar if it is present.    getMenuInflater().inflate(R.menu.main, menu);    return true;   }     /**    * Customize Adapter, so that realize highlighted keywords    */   private class HightKeywordsAdapter extends BaseAdapter {      @Override    public int getCount() {       return dataList.size();    }      @Override    public Object getItem(int position) {       return dataList.get(position);    }      @Override    public long getItemId(int position) {       return position;    }      @Override    public View getView(int position, View convertView, ViewGroup parent) {       View view;     ViewHolder holder;       if (convertView == null) {        holder = new ViewHolder();        view = View.inflate(getApplicationContext(),        R.layout.list_item, null);        holder.tv_name = (TextView) view.findViewById(R.id.tv_name);      holder.tv_en = (TextView) view.findViewById(R.id.tv_en);      holder.tv_sen = (TextView) view.findViewById(R.id.tv_sen);        view.setTag(holder);     } else {      view = convertView;      holder = (ViewHolder) view.getTag();     }       Data data = dataList.get(position);       String name = data.getName();       if (name != null && name.contains(userInput)) {        int index = name.indexOf(userInput);        int len = userInput.length();            Spanned temp = Html.fromHtml(name.substring(0, index)        + "<u><font color=#FF0000>"        + name.substring(index, index + len) + "</font></u>"        + name.substring(index + len, name.length()));        holder.tv_name.setText(temp);     } else {      holder.tv_name.setText(data.getName());     }       holder.tv_en.setText(data.getEn());     holder.tv_sen.setText(data.getSen());       return view;    }   }     static class ViewHolder {    public TextView tv_name;    public TextView tv_en;    public TextView tv_sen;     }    }


布局文件 activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"      xmlns:tools="http://schemas.android.com/tools"      android:layout_width="match_parent"      android:layout_height="match_parent"      tools:context=".MainActivity"       android:background="@drawable/bg">        <EditText          android:id="@+id/et_input"          android:layout_width="match_parent"          android:layout_height="32dp"          android:layout_margin="5dp"          android:hint=""          android:singleLine="true"          android:drawableLeft="@drawable/search_icon"          android:background="@drawable/search_box"/>            <ListView           android:id="@+id/mListView"          android:layout_width="match_parent"          android:layout_height="wrap_content"          android:layout_margin="5dp"          android:layout_below="@id/et_input"          android:cacheColorHint="@android:color/transparent"/>    </RelativeLayout>


 

Data.java

package com.example.highlight;    public class Data {   private String name;   private String en;   private String sen;      public Data(String name, String en, String sen) {    this.name = name;    this.en = en;    this.sen = sen;   }      public String getName() {    return name;   }   public void setName(String name) {    this.name = name;   }   public String getEn() {    return en;   }   public void setEn(String en) {    this.en = en;   }   public String getSen() {    return sen;   }   public void setSen(String sen) {    this.sen = sen;   }     }