仿小米联系人

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_31848763/article/details/51707132

仿小米联系人

这里写图片描述
实现分析:
1.自定义右侧的字母栏,
2.展示数据的listview或者RecycleView
3.圆形TextView
4.集合排序(Comparator)的类
5.中文转拼音

实现代码:
1、自定义右侧的字母栏:
根据控件高度计算字体的大小,字母所占的高度通过滑动改变圆形标记,以及listview的显示;

 protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int heigth = getHeight();
        int width = getWidth();
        //每一个字母的高度
        letter_heigth = heigth / letter.length;
        //圆形标记画笔设置
        round_paint.setColor(Color.parseColor("#ffff00"));
        round_paint.setAntiAlias(true);
        //计算Size
        size = (int) (letter_heigth / 1.5);
        canvas.drawCircle(width / 2, round_Y - (letter_heigth / 2), size / 2 + 7, round_paint);
        for (int i = 0; i < letter.length; i++) {
            paint.setColor(Color.parseColor("#1f2b65"));
            paint.setAntiAlias(true);
            paint.setTextSize(size);
            if (i == select) {
                //如果选中,改变颜色,size
//                paint.setColor(Color.parseColor("#fc1206"));
                paint.setTextSize(size + 10);
            }
            //文本居中
            float letter_X = (width - paint.measureText(letter[0])) / 2;
            float letter_Y = letter_heigth * i + letter_heigth - (size / 2);
            canvas.drawText(letter[i], letter_X, letter_Y, paint);
            paint.reset();
        }
@Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        int action = event.getAction();
        round_Y = (int) event.getY();
        //计算下标
        select = round_Y / letter_heigth;
        //为了美观,不然圆形标记滑出屏幕
        if (round_Y > getHeight() - letter_heigth) {
            round_Y = getHeight() - letter_heigth;
        } else if (round_Y < letter_heigth) {
            round_Y = letter_heigth;
        }
        switch (action) {
            case MotionEvent.ACTION_UP:
                getBackground().setAlpha(0);
                if (select < 0) {
                    select = 0;
                } else if (select >= letter.length) {
                    select = letter.length - 1;
                }
                round_Y = letter_heigth * select + letter_heigth;
                if (listener != null) {
                    listener.onLetterListener(letter[select], -1);
                }
                select = -1;
                invalidate();
                break;
            default:
                setBackgroundColor(Color.parseColor("#c0bebe"));
                getBackground().setAlpha(100);
                if (select >= 0 && select < letter.length) {
                    if (listener != null) {
                        listener.onLetterListener(letter[select], select);
                    }
                    invalidate();
                }
                break;
        }

        return true;
    }

2、展示数据的listview或者RecycleView:
实现方式有2中,这里介绍单布局实现:
通过判断是否是第一次显示,来确定是否隐藏字母栏

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        ListSort.Letter letter = list.get(position);
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.item, null);
            viewHolder = new ViewHolder();
            viewHolder.letter_tv = (TextView) convertView.findViewById(R.id.item_letter);
            viewHolder.name_tv = (TextView) convertView.findViewById(R.id.item_name);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        //判断是否是第一次出现,不是的话就隐藏字母栏
        if (getFristVisibility(letter.frist_Letter) == position) {
            viewHolder.letter_tv.setVisibility(View.VISIBLE);
            viewHolder.letter_tv.setText(letter.frist_Letter);
        } else {
            viewHolder.letter_tv.setVisibility(View.GONE);
        }
        viewHolder.name_tv.setText(letter.name);
        return convertView;
    }

 //得到第一次显示字母下标
    public int getFristVisibility(String string) {
        for (int i = 0; i < list.size(); i++) {
            String str = list.get(i).frist_Letter;
            if (string.equals(str)) {
                return i;
            }
        }
        return -1;
    }

3、圆形TextView:
2种方式:shape标签实现参考圆形圆角Dialog的实现
这里介绍另一种简单粗暴的方式:

 protected void onDraw(Canvas canvas) {
        if (getBackground() != null) {
            getBackground().setAlpha(0);
        }
        radius = getWidth() >= getHeight() ? getHeight() : getWidth();
        paint.setColor(Color.parseColor("#c0bebe"));
        paint.setAntiAlias(true);
        canvas.drawCircle(radius / 2, radius / 2, radius / 2, paint);
        super.onDraw(canvas);

    }

4、集合排序(Comparator)的类
通过实现Comparator来完成:

/*
集合排序
 */
public class ListSort implements Comparator<ListSort.Letter> {
    @Override
    public int compare(Letter lhs, Letter rhs) {
        if (lhs.frist_Letter.equals("@") || rhs.frist_Letter.equals("#")) {
            return -1;
        } else if (lhs.frist_Letter.equals("#") || rhs.frist_Letter.equals("@")) {
            return 1;
        } else {
            return lhs.frist_Letter.compareTo(rhs.frist_Letter);
        }
    }

    public static class Letter {
        String name;
        String frist_Letter;
    }
}

5、中文转拼音:代码太长不贴了
链接地址:使用Java将中文转化为拼音

源码地址

猜你喜欢

转载自blog.csdn.net/qq_31848763/article/details/51707132