如何使用自定义View(流程)?
紧记一定要引入 xmlns:dabin="http://schemas.andoroid.com/apk/res-auto" 这句话,这是命名空间,dabin:mTextSize=”25sp“ 这是对我们attrs.xml中声明属性的赋值。
在构造方法中,获取自定义View的对象,然后对其进行赋值。
①自定义View的属性
②继承View(至少重写2个构造方法)
③重写的 onMeasure(测量当前View的尺寸)、onDraw(绘画)、onLayout(定位)、onTouchEvent(监听)方法
使用教程(可以分为2种,一种是不使用自定义的View属性 另一种就是使用自定义的View属性。)
①先说不使用自定义的View(构造方法至少写2个,我这块写了4个)
- package com.example.dabin.www.day03_viewcircle;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.os.Build;
- import android.support.annotation.RequiresApi;
- import android.util.AttributeSet;
- import android.view.MotionEvent;
- import android.view.View;
- /**
- * Created by Dabin on 2017/4/27.
- */
- public class VirtualKeyView extends View {
- public VirtualKeyView(Context context) {
- super(context);
- }
- public VirtualKeyView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public VirtualKeyView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
- @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
- public VirtualKeyView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- }
- //测量
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
- //绘制
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- //Paint 为画笔 Canvas为画布
- Paint base = new Paint(); //最底部的圈
- Paint middle = new Paint(); //中间的圈
- Paint top = new Paint(); //最顶部的圈
- //选取屏幕中间
- float wi = canvas.getWidth() / 2;
- float he = canvas.getHeight() / 2;
- int baseR = dip2px(getContext(), 150); //设置底部圆半径
- int middleR = dip2px(getContext(), 80); //设置中间圈半径
- int topR = dip2px(getContext(), 50); //设置圆环宽度
- base.setARGB(255, 199, 33, 56); //底部圈设置为红色
- middle.setColor(Color.WHITE); //中间部圈设置为白色
- top.setColor(Color.BLUE); //顶部圈设置为蓝色
- //画笔样式分三种: 1.Paint.Style.STROKE:描边 2.Paint.Style.FILL_AND_STROKE:描边并填充3.Paint.Style.FILL:填充
- //base.setStyle(Paint.Style.STROKE); //给底部圈描边
- //设置描边的粗细,单位:像素px 注意:当setStrokeWidth(0)的时候描边宽度并不为0而是只占一个像素
- //base.setStrokeWidth(20); //底部圈描边的粗细
- //设置画笔为抗齿锯
- base.setAntiAlias(true);
- middle.setAntiAlias(true);
- top.setAntiAlias(true);
- canvas.drawColor(Color.YELLOW); //整体页面颜色
- canvas.drawCircle(wi, he, baseR, base); //底部圈位置大小
- canvas.drawCircle(wi, he, middleR, middle); //中间圈位置大小
- canvas.drawCircle(wi, he, topR, top); //顶部圈位置大小
- canvas.drawText("X", wi, he, base); //底部圈的字体
- }
- //定位
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- }
- //监听
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- return super.onTouchEvent(event);
- }
- //根据手机的分辨率从 dp 的单位 转成为 px(像素)
- public static int dip2px(Context context, float dpValue) {
- final float scale = context.getResources().getDisplayMetrics().density;
- return (int) (dpValue * scale + 0.5f);
- }
- }
我这块直接在onDraw中进行一系列操作,Paint()为画笔, Canvas为画布,其中根据手机分辨率从dp单位转成为px,可以不用,在相应的位置上直接写上数也可以。
其中drawCircle为画圆、drawLine绘制直线、drawRect绘制矩形、drawBitmap绘制位图
效果如下:
②使用View的属性(点击改变数字)
先在res/values下添加一个attrs.xml,在里面定义属性和声明样式
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <attr name="mText" format="string" />
- <attr name="mTextColor" format="color" />
- <attr name="mTextSize" format="dimension" />
- <declare-styleable name="MyView">
- <attr name="mText"/>
- <attr name="mTextColor"/>
- <attr name="mTextSize"/>
- </declare-styleable>
- </resources>
接着在我们的布局文件中声明我们的自定义View
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- xmlns:dabin="http://schemas.android.com/apk/res-auto"
- android:id="@+id/activity_main"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingBottom="@dimen/activity_vertical_margin"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- tools:context="com.dabin.com.www.view.MainActivity">
- <com.example.dabin.www.day04_view.MyView
- android:layout_width="200dip"
- android:layout_height="100dip"
- android:textSize="20sp"
- dabin:mTextSize="25sp"
- dabin:mText="i love you"
- dabin:mTextColor ="#0000ff"
- android:background="#ff0000"/>
- </RelativeLayout>
接着看一下自定义View中的内容
- package com.example.dabin.www.day04_view;
- 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.util.AttributeSet;
- import android.view.MotionEvent;
- import android.view.View;
- /**
- * Created by Dabin on 2017/9/28.
- */
- public class MyView extends View {
- private String mText;// 文字
- private int mTextColor;// 颜色
- private int mTextSize; // 字体大小
- private Rect rect;
- private Paint paint;
- public MyView(Context context) {
- this(context, null);
- }
- public MyView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
- public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- //获取自定义属性的值
- TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MyView, defStyleAttr, 0);
- mText = a.getString(R.styleable.MyView_mText); //获取attrs.xml中的字体
- mTextColor = a.getColor(R.styleable.MyView_mTextColor, Color.BLACK);//设置attrs.xml中的字体颜色
- mTextSize = (int) a.getDimension(R.styleable.MyView_mTextSize, 100);//设置attrs.xml中的字体大小
- a.recycle(); //注意回收
- paint = new Paint();
- paint.setTextSize(mTextSize); //设置字体大小
- paint.setColor(mTextColor); //设置字体颜色
- //获得绘制文本的宽和高
- rect = new Rect();
- paint.getTextBounds(mText, 0, mText.length(), rect);
- }
- // 绘制
- @Override
- protected void onDraw(Canvas canvas) {
- canvas.drawText(mText, getWidth() / 2 - rect.width() / 2, getHeight() / 2 + rect.height() / 2, paint); //绘制文字
- }
- //监听
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_MOVE: //移动
- break;
- case MotionEvent.ACTION_DOWN: //按下
- float a = (float) (Math.random() * 10000); //生成一个随机数
- mText = "" + a;
- invalidate(); //更新视图
- break;
- case MotionEvent.ACTION_UP: //抬起
- break;
- }
- //这句话不要修改
- return super.onTouchEvent(event);
- }
- }
在onTouchEvent()监听方法中设置点击改变值。
效果如下: