您的位置:首页 > 其它

快速索引 (对View的自定义)

2015-12-10 22:07 309 查看

快速索引 (对View的自定义)

快速索引应用场景: 微信好友列表, 联系人通讯录, 应用管理, 文件管理等。

快速索引7步曲:

*1. A-Z索引的绘制.

* 2. 处理Touch事件.

* 3. 提供使用监听\回调

* 4. 汉字转换成拼音.

* 5. 进行排序展示.

* 6. 进行分组.

* 7. 将自定义控件和ListView合体.

1.A-Z索引的绘制

protected void onDraw(Canvas canvas) {

for (int i = 0; i < LETTERS.length; i++) {
String text = LETTERS[i];
// 计算坐标
int x = (int) (cellWidth / 2.0f - mPaint.measureText(text) / 2.0f);
// 获取文本的高度
Rect bounds = new Rect();// 矩形
mPaint.getTextBounds(text, 0, text.length(), bounds);
int textHeight = bounds.height();
int y = (int) (cellHeight / 2.0f + textHeight / 2.0f + i * cellHeight);

// 根据按下的字母, 设置画笔颜色
mPaint.setColor(touchIndex == i ? Color.GRAY : Color.WHITE);

// 绘制文本A-Z
canvas.drawText(text, x, y, mPaint);
}
}


2 处理Touch事件

int touchIndex = -1;
@Override
public boolean onTouchEvent(MotionEvent event) {
int index = -1;
switch (MotionEventCompat.getActionMasked(event)) {
case MotionEvent.ACTION_DOWN:
// 获取当前触摸到的字母索引
index = (int) (event.getY() / cellHeight);
if(index >= 0 && index < LETTERS.length){
// 判断是否跟上一次触摸到的一样
if(index != touchIndex) {
if(listener != null){
listener.onLetterUpdate(LETTERS[index]);
}
Log.d(TAG, "onTouchEvent: " + LETTERS[index]);

touchIndex = index;
}
}
break;
case MotionEvent.ACTION_MOVE:
index = (int) (event.getY() / cellHeight);
if(index >= 0 && index < LETTERS.length){
// 判断是否跟上一次触摸到的一样
if(index != touchIndex){

if(listener != null){
listener.onLetterUpdate(LETTERS[index]);
}
Log.d(TAG, "onTouchEvent: " + LETTERS[index]);

touchIndex = index;
}
}
break;
case MotionEvent.ACTION_UP:
touchIndex = -1;
break;

default:
break;
}
invalidate();

return true;
}


3.提供使用监听\回调

QuickIndexBar bar = (QuickIndexBar) findViewById(R.id.bar);
// 设置监听
bar.setListener(new OnLetterUpdateListener() {
......}


4.汉字转换成拼音

开源包:pingyin4j.jar

public static String getPinyin(String str) {

HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

StringBuilder sb = new StringBuilder();

char[] charArray = str.toCharArray();
for (int i = 0; i < charArray.length; i++) {
char c = charArray[i];
// 如果是空格, 跳过
if(Character.isWhitespace(c)){
continue;
}
if(c >= -127 && c < 128){
// 肯定不是汉字
sb.append(c);
}else {
String s = "";
try {
// 通过char得到拼音集合. 单 -> dan, shan
s = PinyinHelper.toHanyuPinyinStringArray(c, format)[0];
sb.append(s);
} catch (BadHanyuPinyinOutputFormatCombination e) {
e.printStackTrace();
sb.append(s);
}
}
}

return sb.toString();
}


显示字母

protected void showLetter(String letter) {
tv_center.setVisibility(View.VISIBLE);
tv_center.setText(letter);

mHandler.removeCallbacksAndMessages(null);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
tv_center.setVisibility(View.GONE);
}
}, 2000);

}


5.进行排序展示

private void fillAndSortData(ArrayList<Person> persons) {
// 填充数据
for (int i = 0; i < Cheeses.NAMES.length; i++) {
String name = Cheeses.NAMES[i];
persons.add(new Person(name));
}

// 进行排序
Collections.sort(persons);
}


Adapter中:

static class ViewHolder {
TextView mIndex;
TextView mName;

public static ViewHolder getHolder(View view) {
Object tag = view.getTag();
if(tag != null){
return (ViewHolder)tag;
}else {
ViewHolder viewHolder = new ViewHolder();
viewHolder.mIndex = (TextView) view.findViewById(R.id.tv_index);
viewHolder.mName = (TextView) view.findViewById(R.id.tv_name);
view.setTag(viewHolder);
return viewHolder;
}
}


6.进行分组

ViewHolder mViewHolder = ViewHolder.getHolder(view);

Person p = persons.get(position);

String str = null;
String currentLetter = p.getPinyin().charAt(0) + "";
// 根据上一个首字母,决定当前是否显示字母
if(position == 0){
str = currentLetter;
}else {
// 上一个人的拼音的首字母
String preLetter = persons.get(position - 1).getPinyin().charAt(0) + "";
if(!TextUtils.equals(preLetter, currentLetter)){
str = currentLetter;
}
}

// 根据str是否为空,决定是否显示索引栏
mViewHolder.mIndex.setVisibility(str == null ? View.GONE : View.VISIBLE);
mViewHolder.mIndex.setText(currentLetter);
mViewHolder.mName.setText(p.getName());

return view;


7.将自定义控件和ListView结合起来

showLetter(letter);
// 根据字母定位ListView, 找到集合中第一个以letter为拼音首字母的对象,得到索引
for (int i = 0; i < persons.size(); i++) {
Person person = persons.get(i);
String l = person.getPinyin().charAt(0) + "";
if(TextUtils.equals(letter, l)){
// 匹配成功
mMainList.setSelection(i);
break;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: