联系人列表查找控件

此类查找控件有很多帖子,很久没有写过这个控件了  ^_^,闲着练练手。

下面贴出源码:

 

package com.lt.vs.come.custom;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
//import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
//import android.view.ViewGroup;
import android.widget.TextView;

/**
 * Created by 金色VS时空 on 2018/2/20.
 */

public class ContactBannerView extends View {

    public ContactBannerView(Context context) {
        super(context);

    }

    public ContactBannerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ContactBannerView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private Paint mPaint;
    /**
     * 字母列表资源
     */
    private String []letters={"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 char[] chars={'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 OnLetterSelectedListener mOnLetterSelectedListener;

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        initPaint();

        //画初始默认背景色
        if (isTouch){
            //画按下时背景色
            mPaint.setColor(Color.parseColor(pressedColor));
        }else{
            //画默认背景色
            mPaint.setColor(Color.parseColor(defaultColor));
        }
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawRect(0,0,getWidth(),getHeight(),mPaint);


        //绘制字母列表
        mPaint.setColor(Color.BLACK);
        mPaint.setTextSize(35);
        int length=letters.length;
        float padding=getHeight()/length;
        float startX=getWidth()/2;
        float startY=padding-10;
        Log.e("==========",""+startY);
        for (int i = 0; i <length ; i++) {
            if (i==(int)maginY/(int)padding){
                if (mOnLetterSelectedListener!=null){
                    mOnLetterSelectedListener.onLetterSelected(letters[i]);
                }
                if (textInfo!=null){
                    textInfo.setText(letters[i]);
                }
                mPaint.setColor(Color.BLUE);//选中字母绘制蓝色
            }else{
                mPaint.setColor(Color.BLACK);//未选中字母绘制黑色
            }
            canvas.drawText(letters[i],startX-mPaint.measureText(letters[i]) / 2,startY,mPaint);
            startY+=padding;

        }
    }

    /**
     * 获取按下或滑动时的高度
     */
    private float maginY;
    /**
     * 手是否按下本控件
     */
    private boolean isTouch = false;
    /**
     * 列表的触摸事件,获取高度
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action=event.getAction();
        switch (action){
            case MotionEvent.ACTION_DOWN:
                //记录按下时高度
                maginY=event.getRawY();
                isTouch=true;
                if (textInfo!=null){
                    textInfo.setVisibility(VISIBLE);
                }
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                //记录滑动时高度
                maginY=event.getRawY();
                isTouch=true;
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                isTouch=false;
                if (textInfo!=null){
                    textInfo.setVisibility(GONE);
                }
                invalidate();
                break;
        }
        return true;
    }

    /**
     * strokeWidth 绘制笔的粗细,给出方法可以设置,默认为4f
     */
    private static float strokeWidth=4f ;
    public ContactBannerView setStrokeWidth(float strokeWidth) {
        this.strokeWidth = strokeWidth;
        return this;
    }

    private void initPaint() {
        mPaint=new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(strokeWidth);
    }

    /**
     * 外部回调接口,传值为当前选中的字母
     */
    public interface OnLetterSelectedListener{
        void onLetterSelected(String letter);
    }

    /**
     *
     * @param mOnLetterSelectedListener 设置外部调用,监听当前字母变化
     */
    public void setmOnLetterSelectedListener(OnLetterSelectedListener mOnLetterSelectedListener) {
        this.mOnLetterSelectedListener = mOnLetterSelectedListener;
    }

    /**
     * textInfo 外部传入的TextView控件,用于向用户展示选中字母
     */
    private TextView textInfo;
    public void setTextInfo(TextView textInfo) {
        this.textInfo = textInfo;
    }
    /**
     * 按下时控件背景
     */
    private static String pressedColor="#88000000";
    /**
     * 默认控件背景
     */
    private static String defaultColor="#33000000";
    public ContactBannerView setPressedColor(String pressedColor) {
        this.pressedColor = pressedColor;
        return this;
    }
    public ContactBannerView setDefaultColor(String defaultColor) {
        this.defaultColor = defaultColor;
        return this;
    }
}

控件还可以拓展接口。喜欢的点个赞吧

 

这是更新的简洁版本代码如下,很简单不多解释了:

package com.example.myapplication.coustom;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.List;

/**
 * email:1040152329@qq.com
 * Created by gold on 2019/9/25
 * Describe:
 **/
public class ABarView extends View {

    public ABarView(Context context) {
        this(context,null);
    }

    public ABarView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public ABarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
    }

    private Paint paint;
    private int w = 100;
    private int h;
    private List<String> abc;
    private int startX,startY;
    private int perLine;
    private int padding=100;//上下安全距离
    private void initPaint() {
        paint=new Paint();
        paint.setTextSize(12f);
        paint.setAntiAlias(true);
        //设置绘制整体区域
        abc=new ArrayList<>();
        for (int i = 0; i < 26; i++) {
            abc.add(String.valueOf((char)('A' + i)));
        }
        Log.e("@@@@==",abc.toString());
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        w = MeasureSpec.getSize(widthMeasureSpec);      //取出宽度的确切数值
        h = MeasureSpec.getSize(heightMeasureSpec);    //取出高度的确切数值
        perLine = (h-padding*2)/abc.size();
        setMeasuredDimension(w,h);
    }

    private boolean isPressed;
    private List<Point> points=new ArrayList<>();
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.save();
        //绘制常态背景
        paint.setShadowLayer(20 , 0, 0, Color.parseColor("#436EEE"));
        if (!isPressed){
            paint.setColor(Color.parseColor("#F8F8FF"));
        }else{
            paint.setColor(Color.parseColor("#DEDEDE"));
        }
        paint.setStyle(Paint.Style.FILL);
        canvas.drawRect(new Rect(0,0,w,h),paint);

        //绘制字母
        for (int i = 0; i < abc.size(); i++) {
            if (getIndex()==i){
                paint.setColor(Color.parseColor("#000000"));
                paint.setTextSize(sp2px(getContext(),16));
                paint.setStyle(Paint.Style.FILL);
            }else{
                paint.setColor(Color.parseColor("#4682B4"));
                paint.setTextSize(sp2px(getContext(),12));
                paint.setStyle(Paint.Style.STROKE);
            }
            //x表示下限值  y表示上限值
            Point point = new Point();
            String per = abc.get(i);
            Paint.FontMetricsInt metrics=paint.getFontMetricsInt();
            int per_height = metrics.descent-metrics.ascent;
            Rect rect = new Rect();
            paint.getTextBounds(per,0,per.length(),rect);
            int per_width = rect.width();
            paint.setStyle(Paint.Style.FILL);

            startX = w/2-per_width/2;
            startY = (padding+per_height) +perLine*i;
            point.x=startY-perLine/2;
            point.y=startY+perLine/2;
            points.add(point);
            canvas.drawText(per,startX,startY,paint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action =event.getAction();
        switch (action){
            case MotionEvent.ACTION_DOWN:
                isPressed=true;
                Log.e("@@@@==","ACTION_DOWN="+event.getY());
                choosed_ACTION_DOWN(event.getY());
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e("@@@@==","ACTION_MOVE="+event.getY());
                choosed_ACTION_DOWN(event.getY());
                break;
            case MotionEvent.ACTION_UP:
                Log.e("@@@@==","ACTION_UP="+event.getY());
                isPressed=false;
                invalidate();
                break;
        }

        return true;

    }

    private void choosed_ACTION_DOWN(float rawY) {
        for (int i = 0; i < points.size(); i++) {
            if (rawY<=points.get(i).y && i==0){//选中第一个
                setIndex(0);
                return;
            }

            if (rawY>=points.get(i).x && i==points.size()-1){//选中最后一个
                setIndex(abc.size()-1);
                return;
            }

            if (rawY>points.get(i).x && rawY<points.get(i).y){
                setIndex(i);
                return;
            }
        }
    }

    private int index=0;
    private int getIndex() {
        return index;
    }

    /**
     * 刷新选中字母
     * @param index 位置
     */
    private void setIndex(int index) {
        this.index = index;

        if (onLetterChangedListener!=null){
            onLetterChangedListener.onChanged(index);
        }
        //刷新
        invalidate();
    }

    public void setCurrentIndex(String s){
        char c = s.charAt(0);
        Log.e("char=",String.valueOf(c));
        if (c<'Z' || c>'A'){
            setIndex(c-'A');
        }else{
            //防止越界
            setIndex(0);
        }

    }

    /**
     * sp转换成px
     */
    public float sp2px(Context context,float spValue){
        float fontScale=context.getResources().getDisplayMetrics().scaledDensity;
        return spValue*fontScale+0.5f;
    }
    private OnLetterChangedListener onLetterChangedListener;

    public void setOnLetterChangedListener(OnLetterChangedListener onLetterChangedListener) {
        this.onLetterChangedListener = onLetterChangedListener;
    }

    public interface OnLetterChangedListener{
        void onChanged(int index);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值