/** * 方法名:putstr(String keyword, String strtext, Context context) * 功 能:搜索時改變被搜索字段的字體顏色 * 參 數:String keyword, String strtext, Context context * 返回值:SpannableStringBuilder */ public static SpannableStringBuilder putstr(String strText, String keyWord, Context context) { //keyWord是傳的搜索的string,strText傳的是當前item的全部string String docInfo = strText; int keywordIndex = strText.indexOf(keyWord); SpannableStringBuilder style = new SpannableStringBuilder(docInfo); while (keywordIndex != -1) { /** * 關鍵字顏色改變 */ style.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.colorAccent)), keywordIndex, keywordIndex + keyWord.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); int tempkeywordTempIndex = keywordIndex + keyWord.length(); strText = docInfo.substring(tempkeywordTempIndex, docInfo.length()); keywordIndex = strText.indexOf(keyWord); if (keywordIndex != -1) { keywordIndex = keywordIndex + tempkeywordTempIndex; } } return style; } /** * 方法名:putBackgroundStr(String text, String seachText, Context context) * 功 能:搜索時改變被搜索字段的背景顏色 * 參 數:String text, String seachText, Context context * 返回值:SpannableString */ public static SpannableString putBackgroundStr(String text, String seachText, Context context) { //text傳的是當前item的全部string,seachText是傳的搜索的string int keywordIndex = text.indexOf(seachText); SpannableString spanString = new SpannableString(text); BackgroundColorSpan span = new BackgroundColorSpan(context.getResources().getColor(R.color.colorAccent)); spanString.setSpan(span, keywordIndex, keywordIndex + seachText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return spanString; }
//例:
//第一步 activity_main_user.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <SearchView android:queryHint="搜索" android:iconifiedByDefault="false" android:background="#cac5c5" android:id="@+id/mSearchView" android:layout_width="match_parent" android:layout_height="wrap_content" /> <!-- 爲SearchView定義自動補齊的ListView--> <ListView android:id="@+id/mListView" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
//第二步 MainUserActivity代碼:
package com.gang.app.myceshi; import android.content.Context; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.text.Spannable; import android.text.SpannableString; import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.style.BackgroundColorSpan; import android.text.style.ForegroundColorSpan; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.Filter; import android.widget.Filterable; import android.widget.ImageView; import android.widget.ListView; import android.widget.SearchView; import android.widget.TextView; import android.widget.Toast; import com.gang.app.myceshi.bean.User; import java.util.ArrayList; import java.util.List; public class MainUserActivity extends AppCompatActivity { private List<User> mData = new ArrayList<User>(); // 這個數據會改變 private List<User> mBackData; // 這是原始的數據 private ListView mListView; private SearchView mSearchView; private MyAdapter mAdapter; private String seachText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_user); mListView = (ListView) super.findViewById(R.id.mListView); mSearchView = (SearchView) super.findViewById(R.id.mSearchView); //添加數據 initData(); // 設置監聽器 mSearchView.setOnQueryTextListener(new QueryListener()); mListView.setTextFilterEnabled(true); mListView.setOnItemClickListener(new ItemClick()); //適配器 mAdapter = new MyAdapter(this); mListView.setAdapter(mAdapter); } //我這裏寫的是死數據,也可以用User這個Bean類動態添加數據 private void initData() { mData.add(new User(R.mipmap.ic_launcher, "張三")); mData.add(new User(R.mipmap.ic_launcher, "李四")); mData.add(new User(R.mipmap.ic_launcher, "王五")); mData.add(new User(R.mipmap.ic_launcher, "趙六")); //mBackData用來搜索框清空後回覆到原始的數據 mBackData = mData; } // 必須實現Filterable接口 private class MyAdapter extends BaseAdapter implements Filterable { private MyFilter mFilter; private Context context; public MyAdapter(Context context) { this.context = context; } @Override public int getCount() { return mData.size(); } @Override public Object getItem(int position) { return mData.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (null == convertView) { convertView = View.inflate(MainUserActivity.this, R.layout.item_layout, null); } TextView textView = (TextView) convertView.findViewById(R.id.mText); ImageView mImg = (ImageView) convertView.findViewById(R.id.mImg); mImg.setImageResource(mData.get(position).getImg()); String name = mData.get(position).getName(); //在這裏設置搜索時變顏色 if (!TextUtils.isEmpty(seachText)) { SpannableStringBuilder putstr = putstr(name, seachText, context); textView.setText(putstr); // SpannableString string = putBackgroundStr(name, seachText, MainUserActivity.this); // textView.setText(string); } else { textView.setText(name); } return convertView; } @Override public Filter getFilter() { if (null == mFilter) { mFilter = new MyFilter(); } return mFilter; } // 自定義Filter類 class MyFilter extends Filter { @Override // 該方法在子線程中執行 // 自定義過濾規則 protected FilterResults performFiltering(CharSequence constraint) { FilterResults results = new FilterResults(); List<User> newValues = new ArrayList<User>(); String filterString = constraint.toString().trim().toLowerCase(); // 如果搜索框內容爲空,就恢復原始數據 if (TextUtils.isEmpty(filterString)) { newValues = mBackData; } else { // 過濾出新數據 for (int i = 0; i < mBackData.size(); i++) { //通過這個判斷進行過濾,通過mBackData.get(i).getName()進行過濾 if (-1 != mBackData.get(i).getName().toLowerCase().indexOf(filterString)) { newValues.add(mBackData.get(i)); } } } results.values = newValues; results.count = newValues.size(); return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { mData = (List<User>) results.values; if (results.count > 0) { mAdapter.notifyDataSetChanged(); // 通知數據發生了改變 } else { mAdapter.notifyDataSetInvalidated(); // 通知數據失效 } } } } // 搜索文本監聽器 private class QueryListener implements SearchView.OnQueryTextListener { // 當內容被提交時執行 @Override public boolean onQueryTextSubmit(String query) { return false; } // 當搜索框內內容發生改變時執行 @Override public boolean onQueryTextChange(String newText) { if (TextUtils.isEmpty(newText)) { mListView.clearTextFilter(); // 清楚ListView的過濾 seachText = null; } else { mListView.setFilterText(newText); // 設置ListView的過濾關鍵詞 //隱藏彈出的黑框 mListView.dispatchDisplayHint(View.INVISIBLE); seachText = newText; } return true; } } //ListView的item點擊事件 private class ItemClick implements AdapterView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(MainUserActivity.this, mData.get(position).getName(), Toast.LENGTH_SHORT).show(); } } /** * 方法名:putstr(String keyword, String strtext, Context context) * 功 能:搜索時改變被搜索字段的字體顏色 * 參 數:String keyword, String strtext, Context context * 返回值:SpannableStringBuilder */ public static SpannableStringBuilder putstr(String strText, String keyWord, Context context) { //keyWord是傳的搜索的string,strText傳的是當前item的全部string String docInfo = strText; int keywordIndex = strText.indexOf(keyWord); SpannableStringBuilder style = new SpannableStringBuilder(docInfo); while (keywordIndex != -1) { /** * 關鍵字顏色改變 */ style.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.colorAccent)), keywordIndex, keywordIndex + keyWord.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); int tempkeywordTempIndex = keywordIndex + keyWord.length(); strText = docInfo.substring(tempkeywordTempIndex, docInfo.length()); keywordIndex = strText.indexOf(keyWord); if (keywordIndex != -1) { keywordIndex = keywordIndex + tempkeywordTempIndex; } } return style; } /** * 方法名:putBackgroundStr(String text, String seachText, Context context) * 功 能:搜索時改變被搜索字段的背景顏色 * 參 數:String text, String seachText, Context context * 返回值:SpannableString */ public static SpannableString putBackgroundStr(String text, String seachText, Context context) { //text傳的是當前item的全部string,seachText是傳的搜索的string int keywordIndex = text.indexOf(seachText); SpannableString spanString = new SpannableString(text); BackgroundColorSpan span = new BackgroundColorSpan(context.getResources().getColor(R.color.colorAccent)); spanString.setSpan(span, keywordIndex, keywordIndex + seachText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return spanString; } }
//第三步 item_layout.xml :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <ImageView android:id="@+id/mImg" android:src="@mipmap/ic_launcher" android:layout_weight="1" android:layout_width="0dp" android:layout_height="100dp" /> <TextView android:id="@+id/mText" android:gravity="center" android:layout_weight="1" android:layout_width="0dp" android:layout_height="100dp" /> <TextView android:text="年齡18" android:gravity="center" android:layout_weight="1" android:layout_width="0dp" android:layout_height="100dp" /> <TextView android:text="性別男" android:gravity="center" android:layout_weight="1" android:layout_width="0dp" android:layout_height="100dp" /> <TextView android:text="北京" android:gravity="center" android:layout_weight="1" android:layout_width="0dp" android:layout_height="100dp" /> </LinearLayout>
//第四步 User實體Bean類:
public class User { private int img; private String name; public User(int img, String name) { this.img = img; this.name = name; } public int getImg() { return img; } public void setImg(int img) { this.img = img; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
//--------------------------------------------------------------------------------完--------------------------------------------------------------------------------