最近项目中用到 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;
}
}