android 积累一些自定义view的知识
2017-05-27 15:44
405 查看
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 = g 4000 etHeight()/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
相关文章推荐
- 【android 开发知识积累】——属性(Attribute)资源的使用和自定义View组件
- Android 自定义View(2) -- 绘图的基本知识
- android 自定义view基础知识
- android中自定义view涉及到的绘制知识
- android 积累一些RecycylerView的常见用法
- android知识回顾-----自定义view
- Android知识梳理之自定义View
- android 自定义view基础知识
- Android自定义View知识体系
- Android自定义view(一) 知识理解
- Android TextView的一些小知识
- Android知识梳理之自定义ViewGroup
- 用一个低仿界面来说说自定义viewgroup和事件分发的一些知识
- Android杂谈(8)关于自定义View的一些实践+遮罩理解
- Android自定义View研究(二) -- 绘图的基本知识
- android 自定义view 前的基础知识
- Android基础知识之控件系列(1)——TextView及自定义动态TextView
- Android自定义View的一些理解
- Android 从0开始自定义控件之 View 基础知识与概念(一)
- android知识回顾-----自定义view