android 积累一些自定义view的知识

1.仿造QQ计步器(用于统计的自定义View)


步骤:

1.定义属性

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="TongjiView">
        <attr name="firstColor" format="color"></attr>
        <attr name="secondColor" format="color"></attr>
        <attr name="borderWidth" format="dimension"></attr>
        <attr name="tongjiTextSize" format="dimension"></attr>
        <attr name="tongjiTextColor" format="color"></attr>
        <attr name="tongjiText" format="string"></attr>
    </declare-styleable>

</resources>

2.拿属性

    public TongjiView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //获取自定义属性
        Log.i(TAG,"TongjiView3");
        TypedArray array=context.obtainStyledAttributes(attrs,R.styleable.TongjiView);
        mFirstColor=array.getColor(R.styleable.TongjiView_firstColor, Color.GRAY);
        mSecondColor=array.getColor(R.styleable.TongjiView_secondColor,Color.BLACK);
        mTongjiTextColor=array.getColor(R.styleable.TongjiView_tongjiTextColor,Color.BLACK);
        mBorderWidth= (int) array.getDimension(R.styleable.TongjiView_borderWidth,20);
        mTongjiTextSize=array.getDimensionPixelSize(R.styleable.TongjiView_tongjiTextSize,20);
        mTongjiText=array.getString(R.styleable.TongjiView_tongjiText);

        array.recycle();
        initPaint();
        initTextPaint();

    }

3.画两条弧和文字

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.i(TAG,"onDraw");
        mPaint.setColor(mFirstColor);
        //画第一层
        int circleCenter=getWidth()/2;
        int radius=getHeight()/2-mBorderWidth/2;//直接减去画笔的宽度也行
        RectF  rectF=new RectF(circleCenter-radius,circleCenter-radius,circleCenter+radius,circleCenter+radius);
        canvas.drawArc(rectF,135,270,false,mPaint);
        //画第二层
        mPaint.setColor(mSecondColor);
        canvas.drawArc(rectF,135,(270*currentSecondProgress)/maxSecondProgress,false,mPaint);

        //画文字
        Rect textBounds=new Rect();
        mTextPaint.getTextBounds(mTongjiText,0,mTongjiText.length(),textBounds);
        Paint.FontMetricsInt fontMetrics = mTextPaint.getFontMetricsInt();
        int baseLineY = getHeight()/2 - (fontMetrics.bottom-fontMetrics.top)/2- fontMetrics.top;
        canvas.drawText(mTongjiText,getWidth()/2-textBounds.width()/2,baseLineY,mTextPaint);

    }


package com.wyt.hcy.testcustomview;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;


/**
 * Created by hcy on 2017/5/27 0027.
 */

public class TongjiView extends View {

    private int mFirstColor;

    private int mSecondColor;

    private int mBorderWidth;

    private int mTongjiTextColor;

    private int mTongjiTextSize;

    private Paint mPaint;

    private static  final  String TAG="TongjiView";

    private int maxSecondProgress=100;

    private int currentSecondProgress=80;

    private Paint mTextPaint;

    private String mTongjiText;


    public TongjiView(Context context) {
        this(context, null);
        Log.i(TAG,"TongjiView1");
    }

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

        Log.i(TAG,"TongjiView2");
    }

    public TongjiView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //获取自定义属性
        Log.i(TAG,"TongjiView3");
        TypedArray array=context.obtainStyledAttributes(attrs,R.styleable.TongjiView);
        mFirstColor=array.getColor(R.styleable.TongjiView_firstColor, Color.GRAY);
        mSecondColor=array.getColor(R.styleable.TongjiView_secondColor,Color.BLACK);
        mTongjiTextColor=array.getColor(R.styleable.TongjiView_tongjiTextColor,Color.BLACK);
        mBorderWidth= (int) array.getDimension(R.styleable.TongjiView_borderWidth,20);
        mTongjiTextSize=array.getDimensionPixelSize(R.styleable.TongjiView_tongjiTextSize,20);
        mTongjiText=array.getString(R.styleable.TongjiView_tongjiText);

        array.recycle();
        initPaint();
        initTextPaint();

    }

    private void initTextPaint() {
        mTextPaint=new Paint();
        mTextPaint.setAntiAlias(true);//抗锯齿
        mTextPaint.setStyle(Paint.Style.STROKE);
        mTextPaint.setTextSize(mTongjiTextSize);
        mTextPaint.setColor(mTongjiTextColor);
    }

    private void initPaint() {
        Log.i(TAG,"initPaint");
        mPaint=new Paint();
        mPaint.setAntiAlias(true);//抗锯齿
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(mBorderWidth);

    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
      //  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.i(TAG,"onMeasure");
        int width = 0,height = 0;
        int widthMode=MeasureSpec.getMode(widthMeasureSpec);
        int widthSize=MeasureSpec.getSize(widthMeasureSpec);
        int heightMode=MeasureSpec.getMode(heightMeasureSpec);
        int heightSize=MeasureSpec.getSize(heightMeasureSpec);


       //保持一个正方形
        Log.i(TAG,"widthSize:"+widthSize);
        Log.i(TAG,"heightSize:"+heightSize);
        setMeasuredDimension(widthSize,heightSize);
        /*if (widthMode==MeasureSpec.AT_MOST){
            Log.i(TAG,"widthMode==MeasureSpec.AT_MOST");
            width=40;//设置最小宽度
        }else if (widthMode==MeasureSpec.EXACTLY){
            Log.i(TAG,"widthMode==MeasureSpec.EXACTLY");
            width=widthSize;
        }

        if (heightMode==MeasureSpec.AT_MOST){
            Log.i(TAG,"heightMode==MeasureSpec.AT_MOST");
            height=40;
        }else if (heightMode==MeasureSpec.EXACTLY){
            height=heightSize;
            Log.i(TAG,"heightMode==MeasureSpec.EXACTLY");
        }
        //宽高不一致,获取最小的
        int length=width>height?height:width;
        Log.i(TAG,"length:"+length);
        setMeasuredDimension(width>height?height:width,width>height?height:width);  //保持一个正方形
       //*/
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.i(TAG,"onDraw");
        mPaint.setColor(mFirstColor);
        //画第一层
        int circleCenter=getWidth()/2;
        int radius=getHeight()/2-mBorderWidth/2;//直接减去画笔的宽度也行
        RectF  rectF=new RectF(circleCenter-radius,circleCenter-radius,circleCenter+radius,circleCenter+radius);
        canvas.drawArc(rectF,135,270,false,mPaint);
        //画第二层
        mPaint.setColor(mSecondColor);
        canvas.drawArc(rectF,135,(270*currentSecondProgress)/maxSecondProgress,false,mPaint);

        //画文字
        Rect textBounds=new Rect();
        mTextPaint.getTextBounds(mTongjiText,0,mTongjiText.length(),textBounds);
        Paint.FontMetricsInt fontMetrics = mTextPaint.getFontMetricsInt();
        int baseLineY = getHeight()/2 - (fontMetrics.bottom-fontMetrics.top)/2- fontMetrics.top;
        canvas.drawText(mTongjiText,getWidth()/2-textBounds.width()/2,baseLineY,mTextPaint);

    }
}

难点:

1.画弧的时候,

    定义中心点,也就是自定view的中心点坐标(getWidth()/2,getHeight/2)

    定义RectF

    


2.画文字的时候,如何确定基线

      baseLineY = centerY - (fm.bottom-fm.top)/2- fm.top;

3.知识点:View的四个属性: 

top:相对于父容器的左上纵坐标

left:相对于父容器的左上横坐标

right:相对于父容器的右下横坐标

bottom:相对于父容器的右下纵坐标

相对坐标 平移的时候 值不会改变

View 的其他四个参数:

X:View的左上角相对于屏幕的横坐标

Y:View的左上角相对于屏幕的纵坐标

translationX:貌似可以理解为父容器的相对于屏幕的横坐标

translationY::貌似可以理解为父容器的相对于屏幕的纵坐标

4.实现View滑动的三种方式

1.通过View本身的scrollTo/scrollBy方法

2.通过平移动画

3.通过layoutparams





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值