自定义View-案例

自定义输入框

效果:

在这里插入图片描述

代码

@SuppressLint("AppCompatCustomView")
public class CleanTextView extends EditText implements View.OnFocusChangeListener, TextWatcher {
  
private Drawable compoundDrawable;

//控制是否获取焦点

private boolean isFous;

public CleanTextView(Context context) {
    super(context);
}

public CleanTextView(Context context, AttributeSet attrs) {
    this(context,attrs,R.attr.editTextStyle);
}

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

    init();
}

private void init() {
    //获取textView上下左右四个图片的位子
    Drawable[] compoundDrawables = getCompoundDrawables();
    //获取右面图片的位子
    compoundDrawable = compoundDrawables[2];
    if (compoundDrawable == null){
        //加载本地图片
        compoundDrawable = getResources().getDrawable(R.mipmap.ppp);
    }
    //确定图片的位子
    compoundDrawable.setBounds(0,0,compoundDrawable.getIntrinsicWidth(),compoundDrawable.getIntrinsicHeight());
    //初始化监听 焦点事件监听
    setOnFocusChangeListener(this);

    //字体监听
    addTextChangedListener(this);
    //控制图片显隐
    setCompoundIconVisibly(false);

}

private void setCompoundIconVisibly(boolean isvisibly) {
    Drawable drawable = isvisibly ? compoundDrawable : null;
    setCompoundDrawables(getCompoundDrawables()[0],getCompoundDrawables()[1],drawable,getCompoundDrawables()[3]);
}

@Override
public void onFocusChange(View v, boolean isFous) {
    //焦点
    this.isFous = isFous;
    if (!isFous){
        setCompoundIconVisibly(false);
    }else if (this.getText().toString().length() > 0){
        setCompoundIconVisibly(true);
    }
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    //监听字体改变
    if (s.length() > 0 && isFous){
        setCompoundIconVisibly(true);
    }else{
        setCompoundIconVisibly(false);
    }
}

@Override
public void afterTextChanged(Editable s) {

}

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()){
        case MotionEvent.ACTION_UP:
            boolean b = (event.getX() > getWidth() - getTotalPaddingRight()) && (event.getX() < getWidth() - getPaddingRight());
            if (b){
                this.setText("");
            }
            break;
    }
    return super.onTouchEvent(event);
}}

时钟

效果:

在这里插入图片描述

代码

public class My_TimeView extends View {
private int width;
private int height;
private Paint mPaintLine;
private Paint mPaintCircle;
private Paint mPaintHour;
private Paint mPaintMinute;
private Paint mPaintSec;
private Paint mPaintText;
private Calendar mCalendar;
public static final int NEED_INVALIDATE = 0X23;

//每隔一秒,在handler中调用一次重新绘制方法
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {

        switch (msg.what) {
            case NEED_INVALIDATE:
                mCalendar = Calendar.getInstance();
                invalidate();//告诉UI主线程重新绘制
                handler.sendEmptyMessageDelayed(NEED_INVALIDATE, 1000);
                break;
            default:
                break;
        }
    }
};

public My_TimeView(Context context) {
    super(context);
}

public My_TimeView(Context context, AttributeSet attrs) {
    super(context, attrs);

    mCalendar = Calendar.getInstance();

    mPaintLine = new Paint();
    mPaintLine.setColor(Color.BLUE);
    mPaintLine.setStrokeWidth(10);

    mPaintCircle = new Paint();
    mPaintCircle.setColor(Color.GREEN);//设置颜色
    mPaintCircle.setStrokeWidth(10);//设置线宽
    mPaintCircle.setAntiAlias(true);//设置是否抗锯齿
    mPaintCircle.setStyle(Paint.Style.STROKE);//设置绘制风格

    mPaintText = new Paint();
    mPaintText.setColor(Color.BLUE);
    mPaintText.setStrokeWidth(10);
    mPaintText.setTextAlign(Paint.Align.CENTER);
    mPaintText.setTextSize(40);

    mPaintHour = new Paint();
    mPaintHour.setStrokeWidth(8);
    mPaintHour.setAntiAlias(true);
    mPaintHour.setColor(Color.RED);

    mPaintMinute = new Paint();
    mPaintMinute.setStrokeWidth(8);
    mPaintHour.setAntiAlias(true);
    mPaintMinute.setColor(Color.YELLOW);

    mPaintSec = new Paint();
    mPaintSec.setStrokeWidth(8);
    mPaintHour.setAntiAlias(true);
    mPaintSec.setColor(Color.BLUE);

    handler.sendEmptyMessage(NEED_INVALIDATE);//向handler发送一个消息,让它开启重绘
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
    height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
    setMeasuredDimension(width, height);
}

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

    int circleRadius = 330;
    //画出大圆
    canvas.drawCircle(width / 2, height / 2, circleRadius, mPaintCircle);
    //画出圆中心
    canvas.drawCircle(width / 2, height / 2, 20, mPaintCircle);
    //依次旋转画布,画出每个刻度和对应数字
    for (int i = 1; i <= 12; i++) {
        canvas.save();//保存当前画布
        canvas.rotate(360 / 12 * i, width / 2, height / 2);
        //左起:起始位置x坐标,起始位置y坐标,终止位置x坐标,终止位置y坐标,画笔(一个Paint对象)
        canvas.drawLine(width / 2, height / 2 - circleRadius, width / 2, height / 2 - circleRadius + 30, mPaintCircle);
        //左起:文本内容,起始位置x坐标,起始位置y坐标,画笔
        canvas.drawText(String.valueOf(i), width / 2, height / 2 - circleRadius + 70, mPaintText);
        canvas.restore();//
    }

    int minute = mCalendar.get(Calendar.MINUTE);//得到当前分钟数
    int hour = mCalendar.get(Calendar.HOUR);//得到当前小时数
    int sec = mCalendar.get(Calendar.SECOND);//得到当前秒数

    float minuteDegree = minute / 60f * 360;//得到分针旋转的角度
    canvas.save();
    canvas.rotate(minuteDegree, width / 2, height / 2);
    canvas.drawLine(width / 2, height / 2 - 250, width / 2, height / 2 + 40, mPaintMinute);
    canvas.restore();

    float hourDegree = (hour * 60 + minute) / 12f / 60 * 360;//得到时钟旋转的角度
    canvas.save();
    canvas.rotate(hourDegree, width / 2, height / 2);
    canvas.drawLine(width / 2, height / 2 - 200, width / 2, height / 2 + 30, mPaintHour);
    canvas.restore();

    float secDegree = sec / 60f * 360;//得到秒针旋转的角度
    canvas.save();
    canvas.rotate(secDegree, width / 2, height / 2);
    canvas.drawLine(width / 2, height / 2 - 300, width / 2, height / 2 + 40, mPaintSec);
    canvas.restore();
}}

柱状图

效果

在这里插入图片描述

代码

public class My_ZhuView extends View {
    private String[] xData = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
    private String[] yData = {"100","200","300","400","500","600","700","800","900","1000",};
    private List<Integer> list = Arrays.asList(300,200,520,130,750,846,210);
    private int margin = 20;
    private int marginX = 30;
    private int marginY = 30;
    private int pointX;
    private int pointY;
    private int scaleX;
    private int scaleY;
    private Paint paintXY;
    private Paint paintRect;
    private Paint paintValue;


public My_ZhuView(Context context) {
    super(context,null);
}

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

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

public void initView(String[] xData,String[] yData,List<Integer> list){
    this.xData = xData;
    this.yData = yData;
    this.list = list;
}

private void init(){
    pointX = margin+marginX;
    pointY = getHeight() - (margin+marginY);
    scaleX = (getHeight() - 2 * margin-marginX) / xData.length;
    scaleY = (getHeight()-2*margin-marginY)/yData.length;

    paintXY = new Paint();
    paintXY.setStyle(Paint.Style.STROKE);
    paintXY.setAntiAlias(true);
    paintXY.setDither(true);
    paintXY.setColor(Color.BLACK);
    paintXY.setStrokeWidth(3);

    paintRect = new Paint();
    paintRect.setStyle(Paint.Style.STROKE);
    paintRect.setAntiAlias(true);
    paintRect.setDither(true);
    paintRect.setColor(Color.BLACK);
    paintRect.setStrokeWidth(15);

    paintValue = new Paint();
    paintValue.setStyle(Paint.Style.FILL);
    paintValue.setAntiAlias(true);
    paintValue.setDither(true);
    paintValue.setStrokeWidth(1);
}

@Override
protected void onDraw(Canvas canvas) {
    init();
    canvas.drawLine(pointX,pointY,getWidth()-margin,pointY,paintXY);
    canvas.drawLine(pointX,pointY,pointX,margin,paintXY);
    for (int i = 1; i < xData.length; i++) {
        int height = pointY - margin;
        float single = height / Integer.valueOf(yData[yData.length-1]);
        int marginLeft = pointX + scaleX * i;
        canvas.drawText(xData[i-1],marginLeft-53,pointY+25,paintValue);
        RectF rectF = new RectF(marginLeft-50,height-(list.get(i-1)*single),marginLeft-10,pointY);
        canvas.drawRect(rectF,paintRect);
        canvas.drawText(list.get(i-1)+"",marginLeft - 43,height-(list.get(i-1)*single)-10,paintValue);
    }
    for (int i = 1; i < yData.length; i++) {
        int marginTop = scaleY * i;
        canvas.drawText(yData[i-1],pointX,pointY-marginTop,paintValue);
    }
}}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值