写这篇文章在半个月前就打算写,后来因为比较忙,赶项目,然后端午节回家一趟有事给耽误了,今天终于有时间可以补这个篇文章给补上了。
首先说明这个功能要求:
1、首先能够根据数据的首字母进行排序显示,类似于通讯录一样;
2、能够在搜索栏输入关键字进行按关键它检索,并且按规定的顺序对关键字进行排序;
3、对搜索出来的数据包含关键的内容关键字进行高突出显示。
4、输入的关键字时时自动更新检索的内容
这个功能的来源:
由于用户数量比较多,简单的根据首字母来检索速度还是不够快,所以添加关键字自动检索功能,为了突出检索内容,所以将关键高亮显示。并且需要按关键字在内容中的位置先后顺序来进行排序。
没有动手做之前,开始以为这个按关键字在内容在的位置排序是可以通过sql语句来实现的。。。确实是可以通过sql语句实现,但这只是部分数据库可以支持。这也是接下来进走过的哪些坑。
MySql数据库有直接实现的函数,而oracle和sqlite数据库也有,对,没错,android支持的sqlite数据库也有,但是。。。只是5.0及以上的版本支持,有个instr函数,直接order by就可以实现这个小功能,但是5.0以前的版本呢???所以不得不换一个实现方式。后来没有办法只能先把数据按关键字模糊查询出来,然后再按规则进行在内存中进行排序,这样就解决了这个问题。但是当时没有考虑数据多的情况,到后现发现,数据量一多,模糊查询,尤其是%%这种查询真是慢的要死
。没有办法只能又想了一个投机的办法,我给他来个limit,这时瞬间就好了,因为输入的数据是手机号码,全中国的移动手机号码都是1开头的,一个通讯录里面1开头的电话号码该有百分之九十吧。所以来个Limit不管你了,输的关键字越多结果越少。
好了,先给大家看下实现效果图吧
上面基本上把要实现的,如何实现的思路都大概讲下,下面开始讲具体实现以及重要方法代码给贴出来。
获取内容首字母的拼音方法
public static String getPinYinHeadChar(String str) {
String convert = "";
for (int j = 0; j < str.length(); j++) {
char word = str.charAt(j);
String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);
if (pinyinArray != null) {
convert += pinyinArray[0].charAt(0);
} else {
convert += word;
}
}
return convert;
}按名字的首字母进行排序方法
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Collections.sort((List) customList,
new Comparator<CustomForm>() {
@Override
public int compare(CustomForm lhs, CustomForm rhs) {
// 0为等于,1大于,-1小于
if (getPinYinHeadChar(lhs.getName()).charAt(0) > getPinYinHeadChar(
rhs.getName()).charAt(0))
return 1;
else if (getPinYinHeadChar(lhs.getName())
.charAt(0) < getPinYinHeadChar(
rhs.getName()).charAt(0))
return -1;
return 0;
}
});
historyList.add(customList);
handler.sendEmptyMessage(0);
}
}).start();
/**
* 快速排序
*
* @param n
* @param left
* @param right
*/
static void quicksort(ArrayList<CustomSortBean> n, int left, int right) {
int dp;
if (left < right) {
dp = partition(n, left, right);
quicksort(n, left, dp - 1);
quicksort(n, dp + 1, right);
}
}
/**
* 快速排序找出中间标号
*
* @param n
* @param left
* @param right
* @return
*/
static int partition(ArrayList<CustomSortBean> n, int left, int right) {
CustomSortBean pivot = n.get(left);
while (left < right) {
while (left < right
&& n.get(right).getPosition() >= pivot.getPosition())
right--;
n.set(left, n.get(right));
while (left < right
&& n.get(left).getPosition() <= pivot.getPosition())
left++;
n.set(right, n.get(left));
}
n.set(left, pivot);
return left;
}通过将列表按具体规则调用快排进行排序
/**
* 将获取的List进行排序
*
* @param customList
* @param key
* @return
*/
public ArrayList<CustomForm> sortList(ArrayList<CustomForm> customList,
String key) {
ArrayList<CustomForm> list = new ArrayList<CustomForm>();
ArrayList<CustomSortBean> index = new ArrayList<CustomSortBean>();
for (int i = 0; i < customList.size(); i++) {
CustomSortBean bean = new CustomSortBean();
bean.setIndex(i);
if (customList.get(i).getMobile().indexOf(key) > -1) {// 手机号码优先
bean.setPosition(customList.get(i).getMobile().indexOf(key));
} else if (customList.get(i).getName().indexOf(key) > -1) {// 名字其次
int po = (customList.get(i).getName().indexOf(key) + 1) * 200
+ i;// 体现位置的顺序大于本来顺序
bean.setPosition(po);
} else {
if (customList.get(i).getVillage() != null) {// 村组最后
int po = (customList.get(i).getVillage().indexOf(key) + 2)
* 400 + i;
bean.setPosition(po);
}
}
index.add(bean);
}
quicksort(index, 0, index.size() - 1);
for (int i = 0; i < index.size(); i++) {
list.add(customList.get(index.get(i).getIndex()));
}
return list;
}关键字高亮显示的自定义View,需要使用SpannableStringBuilder方法来实现:
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
import android.widget.TextView;
public class SpannableTextView extends TextView {
public SpannableTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setSpecifiedTextsColor(String text, String specifiedTexts,
int color) {
List<Integer> sTextsStartList = new ArrayList<Integer>();
specifiedTexts = specifiedTexts.toLowerCase();
int sTextLength = specifiedTexts.length();
String temp = text.toLowerCase();
int lengthFront = 0;// 记录被找出后前面的字段的长度
int start = -1;
do {
start = temp.indexOf(specifiedTexts);
if (start != -1) {
start = start + lengthFront;
sTextsStartList.add(start);
lengthFront = start + sTextLength;
temp = text.substring(lengthFront);
}
} while (start != -1);
SpannableStringBuilder styledText = new SpannableStringBuilder(text);
for (Integer i : sTextsStartList) {
styledText.setSpan(new ForegroundColorSpan(color), i, i
+ sTextLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
setText(styledText);
}
}
如果看不明白的,或者需要代码来理解了,我可以为大家整理一套简单的demo。欢迎大家来骚扰
本文介绍了一种Android应用中的关键字搜索功能,包括按首字母排序、关键字检索、关键字高亮显示和实时更新。在实现过程中,由于不同数据库对关键字排序支持不一,作者采取了在内存中对模糊查询结果进行排序的解决方案,同时通过Limit优化大量数据的搜索性能。文章提供了实现思路和关键代码。

5812

被折叠的 条评论
为什么被折叠?



