首页 > 学院 > 开发设计 > 正文

一步一步学自定义View(1.简单入门)

2019-11-08 00:33:31
字体:
来源:转载
供稿:网友

1、自定义View

android中可能遇到很多需求要求自定义view,一般github上都有各种各样的酷炫效果自定义view,特别是仪表盘,柱状图,饼状图都有,但还是不免遇到一些特别的需求,自定义样式难以修改开源库,因此还是需要自己来实现。接下来记录自己一点一点学习自定义view的过程。接下来主要实现这样的效果(简单的实现画圆,和简单的动画效果) 项目目录结构 这里写图片描述 这里写图片描述

2、自定义view中构造方法

构造方法用来初始化view,一般的定义的view比如圆的宽,高,圆的颜色等,都是在我们xml文件中配置的,因此,我们必须重写带有AttributeSet的构造方法

/** * 当需要在xml中声明此控件,则需要实现此构造函数 * 并且在构造函数中把自定义的属性与控件的数据成员连接起来 * * @param context * @param attrs */ public View1(Context context, AttributeSet attrs) { super(context, attrs); //如果xml文件中没有文件,则使用后面默认值; paintOut = new Paint(); paintIn=new Paint(); //从attrs读取属性 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyView1); this.cicle_in_color = typedArray.getColor(R.styleable.MyView1_cicle_in_color, Color.BLACK); this.cicle_in_radius = typedArray.getDimension(R.styleable.MyView1_cicle_in_radius, 100); this.cicle_in_StrokeWidth = typedArray.getDimension(R.styleable.MyView1_cicle_in_StrokeWidth, 5); this.cicle_out_color = typedArray.getColor(R.styleable.MyView1_cicle_out_color, Color.BLACK); this.cicle_out_radius = typedArray.getDimension(R.styleable.MyView1_cicle_out_radius, 30); this.cicle_out_StrokeWidth = typedArray.getDimension(R.styleable.MyView1_cicle_out_StrokeWidth, 5); //打开抗锯齿 paintOut.setAntiAlias(true); //设置xml文件中的属性 paintOut.setColor(cicle_out_color); paintOut.setStyle(Paint.Style.STROKE); paintOut.setStrokeWidth(cicle_out_StrokeWidth); paintIn.setColor(cicle_in_color); paintIn.setStyle(Paint.Style.STROKE); paintIn.setStrokeWidth(cicle_in_StrokeWidth); //回收TypedArray,以便后面重用 typedArray.recycle(); }

3、在xml文件中配置自定义view的属性、

在values下新建attrs.xml文件

<?xml version="1.0" encoding="utf-8"?><resources> //自定义属性名,定义公共属性 <attr name="textSize" format="dimension"></attr> <attr name="textTitle" format="string"></attr> <attr name="textColor" format="color"></attr> <attr name="cicle_color" format="color"></attr> <attr name="cicle_radius" format="dimension"></attr> <declare-styleable name="MyView1"> <attr name="cicle_color"></attr> <attr name="cicle_out_color" format="color"></attr> <attr name="cicle_out_radius" format="dimension"></attr> <attr name="cicle_out_StrokeWidth" format="dimension"></attr> <attr name="cicle_in_color" format="color"></attr> <attr name="cicle_in_radius" format="dimension"></attr> <attr name="cicle_in_StrokeWidth" format="dimension"></attr> </declare-styleable> <declare-styleable name="MyView2"> <attr name="textSize"></attr> <attr name="textTitle"></attr> <attr name="textColor"></attr> <attr name="cicle_color"></attr> <attr name="cicle_StrokeWidth" format="dimension"></attr> <attr name="cicle_radius"></attr> </declare-styleable></resources>

这样,就可以在界面的xml文件中配置这些属性,添加命名空间和声明的属性名称 这里写图片描述

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res-auto" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin"> <view.viewActivity1.View1 android:layout_width="100dp" android:layout_height="100dp" custom:cicle_in_StrokeWidth="5dp" custom:cicle_in_color="#00ff00" custom:cicle_in_radius="20dp" custom:cicle_out_StrokeWidth="5dp" custom:cicle_out_color="#ff0000" custom:cicle_out_radius="45dp" /> <view.viewActivity1.View2 android:id="@+id/view2" android:layout_width="100dp" android:layout_height="100dp" custom:cicle_StrokeWidth="5dp" custom:cicle_color="#0000ff" /></LinearLayout>

4、自定义view的主要代码,在代码中做详解

1、画圆的主要代码

package view.viewActivity1;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import android.view.View;import com.example.cusotmerview.R;/** * Created by yuxiaogang on 2017/2/23. */public class View1 extends View { PRivate Paint paintOut; private Paint paintIn; private int cicle_in_color; private float cicle_in_radius; private float cicle_in_StrokeWidth; private int cicle_out_color; private float cicle_out_radius; private float cicle_out_StrokeWidth; public View1(Context context) { super(context); } /** * 当需要在xml中声明此控件,则需要实现此构造函数 * 并且在构造函数中把自定义的属性与控件的数据成员连接起来 * * @param context * @param attrs */ public View1(Context context, AttributeSet attrs) { super(context, attrs); //如果xml文件中没有文件,则使用后面默认值; paintOut = new Paint(); paintIn=new Paint(); //从attrs读取属性 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyView1); this.cicle_in_color = typedArray.getColor(R.styleable.MyView1_cicle_in_color, Color.BLACK); this.cicle_in_radius = typedArray.getDimension(R.styleable.MyView1_cicle_in_radius, 100); this.cicle_in_StrokeWidth = typedArray.getDimension(R.styleable.MyView1_cicle_in_StrokeWidth, 5); this.cicle_out_color = typedArray.getColor(R.styleable.MyView1_cicle_out_color, Color.BLACK); this.cicle_out_radius = typedArray.getDimension(R.styleable.MyView1_cicle_out_radius, 30); this.cicle_out_StrokeWidth = typedArray.getDimension(R.styleable.MyView1_cicle_out_StrokeWidth, 5); //打开抗锯齿 paintOut.setAntiAlias(true); //设置xml文件中的属性 paintOut.setColor(cicle_out_color); paintOut.setStyle(Paint.Style.STROKE); paintOut.setStrokeWidth(cicle_out_StrokeWidth); paintIn.setColor(cicle_in_color); paintIn.setStyle(Paint.Style.STROKE); paintIn.setStrokeWidth(cicle_in_StrokeWidth); //回收TypedArray,以便后面重用 typedArray.recycle(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); /** * 第一个参数:圆心x坐标 * 第二个参数:圆心y坐标 * 第三个参数:半径 * 第四个参数:paint画笔 */ canvas.drawCircle(100, 100, cicle_out_radius, paintOut); canvas.drawCircle(100, 100, cicle_in_radius, paintIn); }}

2、画圆有动画效果的代码

package view.viewActivity1;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RectF;import android.util.AttributeSet;import android.view.View;import com.example.cusotmerview.R;/** * Created by yuxiaogang on 2017/2/23. */public class View2 extends View { private Paint circlePaint; private RectF circleRect; private int cicle_out_color; private float cicle_out_radius; private float cicle_out_StrokeWidth; private int mCurrentPercent; public int getmTargetPercent() { return mTargetPercent; } public void setmTargetPercent(int mTargetPercent) { this.mTargetPercent = mTargetPercent; } private int mTargetPercent; private float mCurrentAngle; private float mStartSweepValue; public View2(Context context) { super(context); } /** * 当需要在xml中声明此控件,则需要实现此构造函数 * 并且在构造函数中把自定义的属性与控件的数据成员连接起来 * * @param context * @param attrs */ public View2(Context context, AttributeSet attrs) { super(context, attrs); //如果xml文件中没有文件,则使用后面默认值; circlePaint = new Paint(); //从attrs读取属性 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyView2); this.cicle_out_color = typedArray.getColor(R.styleable.MyView2_cicle_color, Color.BLACK); this.cicle_out_radius = typedArray.getDimension(R.styleable.MyView2_cicle_radius, 30); this.cicle_out_StrokeWidth = typedArray.getDimension(R.styleable.MyView2_cicle_StrokeWidth, 5); //回收TypedArray,以便后面重用 typedArray.recycle(); init(); } private void init() { mStartSweepValue = 180; //当前角度 mCurrentAngle = 0; //当前百分比 mCurrentPercent = 0; circleRect = new RectF(20, 20, getWidth() - 20, getWidth() - 20); } public void setNumber(int size) { mCurrentPercent = 0; mTargetPercent = size; mCurrentAngle = 0; postInvalidate(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //打开抗锯齿 circlePaint.setAntiAlias(true); //设置xml文件中的属性 circlePaint.setColor(cicle_out_color); circlePaint.setStyle(Paint.Style.STROKE); circlePaint.setStrokeWidth(cicle_out_StrokeWidth); // 通过上下左右4个边的坐标来表示一个矩形,画圆就在这个矩形区域内; circleRect = new RectF(10, 10, getWidth() - 10, getWidth() - 10); /** * drawArc() * 第一个参数:圆弧外的轮廓区域 * 第二个参数,圆弧开始的角度 * 第三个参数,圆弧顺时针扫过的角度 * 第四个参数, 如果为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形 * 第五个参数,画布 */ canvas.drawArc(circleRect, mStartSweepValue, mCurrentAngle, false, circlePaint); if (mCurrentPercent < mTargetPercent) { //当前百分比+1 mCurrentPercent += 2; //当前角度+360 mCurrentAngle += 7.2; //每100ms重画一次 postInvalidateDelayed(100); } }}
上一篇:剑指offer(题三)

下一篇:目录

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表