快速索引

来源:互联网 发布:儿童冬季内衣淘宝网 编辑:程序博客网 时间:2024/06/06 00:41

应用场景:联系人 微信,省市列表,应用管理,文件管理,需要快速定位的列表

 

实现步骤:

-绘制静态的A-Z字母列表

-响应触摸事件

-提供监听回调

-获取汉字拼音,首字母

-根据拼音进行排序

-根据首字母分组

-把监听回调和listview结合起来

 

 

 

 

1.1.1. -绘制静态的A-Z字母列表

-在构造方法中初始画笔paint

-onMesure()中获取单元格的高度和宽度

-onDraw()中画出每个字母

 

public class QuickIndex extends View {

    private static final String[] LETTERS = new String[]{
            "A", "B", "C", "D", "E", "F",
            "G", "H", "I", "J", "K", "L",
            "M", "N", "O", "P", "Q", "R",
            "S", "T", "U", "V", "W", "X",
            "Y", "Z"
    };
    private Paint paint;
    private int cellWidth;
    private float cellHeight;
    public QuickIndex(Context context) {
        this(context, null);
    }
    public QuickIndex(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public QuickIndex(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //初始化画笔
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);//抗锯齿的flag
//        paint.setTypeface(Typeface.DEFAULT_BOLD);//画笔文本加粗
        paint.setColor(Color.WHITE);
        paint.setTextSize(50);
    }
    //画画
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //遍历26个英文字母,计算坐标,进行绘制;这样能够得到良好的适配效果
        for (int i = 0; i < LETTERS.length; i++) {
            String letter = LETTERS[i];
            float x = cellWidth * 0.5f - paint.measureText(letter) * 0.5f;
            Rect bounds = new Rect();
            paint.getTextBounds(letter, 0, letter.length(), bounds);
            float y = cellHeight * 0.5f + bounds.height() * 0.5f + i * cellHeight;
            canvas.drawText(letter, x, y, paint);
//            canvas.drawText(letter, 30, 60 + paint.getTextSize() * i, paint);
        }
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //当前控件的宽高
        int mWidth = getMeasuredWidth();
        int mHeight = getMeasuredHeight();
        //当前单元格的宽度就是当前控件的宽度
        cellWidth = mWidth;
        //当前单元格的高度
        cellHeight = mHeight * 1.0f / LETTERS.length;
    }

 

1.1.2. -响应触摸事件

private int lastIndex = -1;//定义上次触摸的索引
@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            getCurrentIndex(event);
            break;
        case MotionEvent.ACTION_MOVE:
            getCurrentIndex(event);
            break;
        case MotionEvent.ACTION_UP:
            lastIndex = -1;
            break;
    }
    return true;//自己消费触摸事件
}

 //获取当前字母索引并记录,手指触摸的地方与上次触摸的地方的索引不一样打印吐司
private void getCurrentIndex(MotionEvent event) {
    downy = event.getY();
    //根据y值计算当前按下的字母的索引
    currentIndex = (int) (downy / cellHeight);
    if (currentIndex != lastIndex) {
        if (currentIndex > 0 && currentIndex < LETTERS.length) {
            Utils.showToast(getContext(), LETTERS[currentIndex]);
            //记录当前index
            lastIndex = currentIndex;//将当前索引赋值给
        }
    }
}

 

1.1.3. -提供监听回调

-定义监听器,并生成setget方法

-在检测到字母大声改变的时候,调用监听器里面的方法

-在关心字母变化的activity中设置监听器,打印吐司

 

1.

public interface OnLetterUpdateListener {
    void OnLetterUpdate(String letter);
}
public OnLetterUpdateListener mOnLetterUpdateListener;

 

2.

if (currentIndex != lastIndex) {
        //调用监听事件里面的方法
        if (mOnLetterUpdateListener != null) {
            mOnLetterUpdateListener.OnLetterUpdate(letter);
        }

}

 

3.

quickindex.setmOnLetterUpdateListener(new QuickIndex.OnLetterUpdateListener() {
    @Override
    public void OnLetterUpdate(String letter) {
        Utils.showToast(QuickIndexActivity.this, letter);
    }
});

 

1.1.4. -获取汉字拼音,首字母

-引入pinyin4jjar包,然后复制粘贴老师的PinYinUtils.java

-在布局里定义listview,在适配器中的getview中的布局中定义两个textview:首字母和名字

-将好汉的名字以及拼音首字母都显示出来

1.1.5. -根据拼音进行排序,和分组

-activity中对集合中数据进行填充和排序

-在适配器中判断并首字母的显示

 

1.


 //对集合中数据进行填充和排序
private void fillAndSortData(ArrayList<Haohan> haohans) {
    // 填充
    for (int i = 0; i < Cheeses.NAMES.length; i++) {
        String name = Cheeses.NAMES[i];
        haohans.add(new Haohan(name));//像集合中添加数据
    }
    // 排序,这个操作需要对HaoHan类实现Conmparebale接口,重写compareTo()
    Collections.sort(haohans);
}

 

2.

Haohan haohan = haohans.get(position);
//当前首字母
String currentStr = haohan.getPinyin().charAt(0) + "";
String indexStr = null;
//如果是第一个,字母直接显示
if (position == 0) {
    indexStr = currentStr;
} else {
    //判断当前首字母和上一个条目的首字母是否一致,不一致的时候显示
    String lastStr = haohans.get(position - 1).getPinyin().charAt(0) + "";
    if (!TextUtils.equals(lastStr, currentStr)) {//不一致时给indexStr赋值
        indexStr = currentStr;
    }
}
//对控件赋值
holder.index.setVisibility(indexStr != null ? View.VISIBLE : View.GONE);
holder.index.setText(currentStr);
holder.name.setText(haohan.getName());

 

1.1.6. -把监听回调和listview结合起来

quickindex.setmOnLetterUpdateListener(new QuickIndex.OnLetterUpdateListener() {
    @Override
    public void OnLetterUpdate(String letter) {
        //打印吐司,并跳转到相应位置
        Utils.showToast(QuickIndexActivity.this, letter);
        for (int i = 0; i < haohans.size(); i++) {
            String l = haohans.get(i).getPinyin().charAt(0) + "";
            if (TextUtils.equals(letter, l)) {
                lv.setSelection(i);
                break;
            }
        }
    }
});

 

 

1.1.7. -点击快速索引bar,让里面的字母颜色发生变化

触摸事件结束后,刷新view:调用invalidate(),这样会重新调用ondraw()方法

invalidate()

cavas.draw()之前,决定画笔颜色

paint.setColor(i == lastIndex ? Color.GRAY : Color.WHITE);

1.1.8. -textview代替吐司

在布局文件中定义textview,让他显示在中央,然后在代码里面控制他的显示和隐藏

private Handler handler = new Handler();
/**
 * 显示文本
 */
private void showLetter(String letter) {
    tvToast.setText(letter);
    tvToast.setVisibility(View.VISIBLE);
    //移除之前所有的延时操作
    handler.removeCallbacksAndMessages(null);
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            tvToast.setVisibility(View.INVISIBLE);
        }
    }, 800);
}

0 0
原创粉丝点击