Android 自定义View——联系人右侧字母索引

现在很多app里面都有侧边栏字母索引列表,看着效果很炫酷,其实不难,那我们现在也来一起自定义一个侧边栏索引列表。

没图说个毛

GIF图:
------------------------------------开始撸代码-------------------------------------
一.首先我们先来写右侧的侧边栏
 
public class SideBar extends View {

    /*绘制的列表导航字母*/
    private String words[] = {"↑", "☆", "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 wordsPaint;
    /*按下字母背景画笔*/
    private Paint bgPaint;
    /*每一个item的宽度*/
    private int wordWidth;
    /*每一个item的高度*/
    private int wordHeight;
    /*手指按下的字母索引*/
    private int touchIndex = -1;
    /*手指按下的字母改变接口*/
    private onWordsChangeListener listener;

    private TextView mTextDialog;

获取到控件的宽高,计算出每个item的宽高
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        wordWidth = getMeasuredWidth();
        int height = getMeasuredHeight();
        wordHeight = height / words.length;
    }

开始画字母列表
 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int i = 0; i < words.length; i++) {

            wordsPaint.setTypeface(Typeface.DEFAULT);
            wordsPaint.setAntiAlias(true);
            wordsPaint.setTextSize(DensityUtils.dp2px(getContext(), 14));

            // 是按下的字母则绘制背景
            if (touchIndex == i) {
                canvas.drawCircle(wordWidth / 2, wordHeight / 2 + i * wordHeight, wordHeight / 2, bgPaint);
                wordsPaint.setColor(Color.WHITE);
            } else {
                wordsPaint.setColor(Color.parseColor("#666666"));
            }

            //获取文字的宽高
            Rect rect = new Rect();
            wordsPaint.getTextBounds(words[i], 0, words[i].length(), rect);
            //得到文字的X坐标
            float wordX = wordWidth / 2 - wordsPaint.measureText(words[i]) / 2;
            float wordY = wordHeight / 2 + rect.height() / 2 + wordHeight * i;
            canvas.drawText(words[i], wordX, wordY, wordsPaint);
            wordsPaint.reset();
        }
    }

二.处理触摸事件:

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN | MotionEvent.ACTION_MOVE:
                float y = event.getY();
                //关键点===获得我们按下的是那个索引(字母)
                int index = (int) (y / wordHeight);
                touchIndex = index;
                //防止数组越界
                if (listener != null && 0 <= touchIndex && touchIndex <= words.length - 1) {
                    //回调按下的字母
                    listener.wordsChange(words[touchIndex]);
                    invalidate();
                    if (mTextDialog != null) {
                        mTextDialog.setText(words[index]);
                        mTextDialog.setVisibility(View.VISIBLE);
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                touchIndex = -1;
                invalidate();
                if (mTextDialog != null) {
                    mTextDialog.setVisibility(View.GONE);
                }
                break;
        }
        return true;

    }
   /*手指按下了哪个字母的回调接口*/
    public interface onWordsChangeListener {
        void wordsChange(String words);
    }

三.listview列表:将汉字转为拼音排序
 List<Person> mSortList = new ArrayList<Person>();

        for (int i = 0; i < date.length; i++) {
            Person sortModel = new Person();
            sortModel.setName(date[i]);
            //汉字转换成拼音
            String pinyin = characterParser.getSelling(date[i]);
            String sortString = pinyin.substring(0, 1).toUpperCase();

            // 正则表达式,判断首字母是否是英文字母
            if (sortString.matches("[A-Z]")) {
                sortModel.setLetter(sortString.toUpperCase());
            } else {
                sortModel.setLetter("#");
            }

            mSortList.add(sortModel);
        }
Collections.sort(mSortList, pinyinComparator);
 sideBar.setOnWordsChangeListener(new SideBar.onWordsChangeListener() {
            @Override
            public void wordsChange(String words) {
                if ("↑".equals(words)) {
                    listview.setSelection(0);
                } else if ("☆".equals(words)) {
                    listview.setSelection(1);
                } else {
                    //该字母首次出现的位置
                    int position = myAdapter.getPositionForSection(words.charAt(0));
                    if (position != -1) {
                        listview.setSelection(position+2);
                    }
                }
            }
        });


好啦! 大工告成,是不是很简单呢?嘿嘿。。。










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值