Android自定义控件之循环旋转弧度不断变化圆弧的控件
2017-05-07 14:15
941 查看
Android自定义控件的绘制流程为Measure(测量)–>Layout(布局)–>Draw(绘制)。测量控件的宽高,需要重写onMeasure方法,其中涉及到一个关键的知识点:MeasureSpec类。一个MeasureSpec封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求。一个MeasureSpec由大小和模式组成。它有三种模式:UNSPECIFIED(未指定),父元素不对子元素施加任何束缚,子元素可以得到任意想要的大小,一般用于AdapterView,比如Listview,Gridview等;EXACTLY(精确),父元素决定自元素的确切大小,子元素将被限定在给定的边界里而忽略它本身大小或者子元素的尺寸是精确的,比如 android:layout_width=”50dp” android:layout_height=”50dp”;AT_MOST(至多),子元素至多达到指定大小的值,也就是只要不超过父容器所给定的大小,子元素多大都可以。
它常用的三个函数:
1.static int getMode(int measureSpec):根据提供的测量值(格式)提取模式(上述三个模式之一)
2.static int getSize(int measureSpec):根据提供的测量值(格式)提取大小值(这个大小也就是我们通常所说的大小)
3.static int makeMeasureSpec(int size,int mode):根据提供的大小值和模式创建一个测量值(格式)。
对于一般的控件,我们只需要判断它是MeasureSpec.EXACTLY还是MeasureSpec.AT_MOST。MeasureSpec.EXACTLY代表子元素的尺寸是确定的了,比如子容器是match_parent,或者子元素的尺寸是固定尺寸;MeasureSpec.AT_MOST代表在父容器的尺寸范围内,子元素要多大就是多大,比如wrap_content.。
本篇文章所要介绍的是如何自定义一个循环旋转圆弧不断变化的控件。
首先要继承于View,重写构造方法,在构造方法中初始化画笔等等。
重写View的onMeasure方法,测量控件的宽高,调用setMeasuredDimension方法,设置控件的宽高,否则控件的宽高默认为父容器的宽高。
由于本demo中没有涉及到控件的自定义布局,所以没有重写onLayout方法。重写onDraw方法,绘制背景圆形、弧度不断变化圆弧和旋转canvas,并调用postInvalidateDelayed方法,定时刷新界面
在布局文件中使用该控件
它常用的三个函数:
1.static int getMode(int measureSpec):根据提供的测量值(格式)提取模式(上述三个模式之一)
2.static int getSize(int measureSpec):根据提供的测量值(格式)提取大小值(这个大小也就是我们通常所说的大小)
3.static int makeMeasureSpec(int size,int mode):根据提供的大小值和模式创建一个测量值(格式)。
对于一般的控件,我们只需要判断它是MeasureSpec.EXACTLY还是MeasureSpec.AT_MOST。MeasureSpec.EXACTLY代表子元素的尺寸是确定的了,比如子容器是match_parent,或者子元素的尺寸是固定尺寸;MeasureSpec.AT_MOST代表在父容器的尺寸范围内,子元素要多大就是多大,比如wrap_content.。
本篇文章所要介绍的是如何自定义一个循环旋转圆弧不断变化的控件。
首先要继承于View,重写构造方法,在构造方法中初始化画笔等等。
public MyArc02(Context context, AttributeSet attrs) { super(context, attrs); //实例化画笔 paint = new Paint(); //控件的宽度 width = getResources().getDimensionPixelSize(R.dimen.header_width); height = width; //圆弧的矩形范围 oval = new RectF(15, 15, width - 15, width - 15); //圆弧的半径 radius = getResources().getDimensionPixelSize(R.dimen.radius); cx = width / 2; cy = cx; }
重写View的onMeasure方法,测量控件的宽高,调用setMeasuredDimension方法,设置控件的宽高,否则控件的宽高默认为父容器的宽高。
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int mWidth = MeasureSpec.getSize(widthMeasureSpec); int mHeight = MeasureSpec.getSize(heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int HeightMode = MeasureSpec.getMode(widthMeasureSpec); System.out.println("宽度: " + mWidth); System.out.println("高度: " + mHeight); //width是绘制控件所需要的最大宽度尺寸,height为绘制控制所需的最大高度尺寸 int measuredWidth = (int) (widthMode == MeasureSpec.EXACTLY ? mWidth : width); int measuredHeight = (int) (HeightMode == MeasureSpec.EXACTLY ? mHeight : height); setMeasuredDimension(measuredWidth, measuredHeight); }
由于本demo中没有涉及到控件的自定义布局,所以没有重写onLayout方法。重写onDraw方法,绘制背景圆形、弧度不断变化圆弧和旋转canvas,并调用postInvalidateDelayed方法,定时刷新界面
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); paint.setStrokeWidth(5); drawRoundBackground(canvas); drawRunningArc(canvas); } private void drawRoundBackground(Canvas canvas) { paint.setColor(Color.WHITE); paint.setStyle(Paint.Style.FILL); canvas.drawCircle(cx, cy, radius, paint); paint.setColor(Color.GRAY); paint.setStyle(Paint.Style.STROKE); paint.setAlpha(20); canvas.drawCircle(cx, cy, radius, paint); } /** * 画转动圆弧 * @param canvas */ private void drawRunningArc(Canvas canvas) { paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(10); startAngle += deltaAngle; if (sweepAngle >= 360 - deltaAngle) { flag = true; } if (sweepAngle <= deltaAngle ) { flag = false; } if (flag) { sweepAngle -= deltaAngle; }else { sweepAngle += deltaAngle; } angle += deltaAngle; canvas.rotate(angle, cx, cy); canvas.drawArc(oval, startAngle, sweepAngle, false, paint); //每隔200毫秒,刷新界面 postInvalidateDelayed(200); }
在布局文件中使用该控件
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <com.example.arc.MyArc02 android:id="@+id/arc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/ic_launcher" /> </FrameLayout>
相关文章推荐
- Android 自定义控件初级 多层按钮旋转控件
- 2010.06.05日志:Android Gallery左右循环旋转方法
- Android 自定义控件 单页翻书控件
- android 旋转按钮和旋转变化动画
- 2013新春奉送:Android摄像头开发完美demo---(循环聚焦,缩放大小,旋转picture,查询支持的picturesize, ImageButton按键效果)
- android - 自定义(组合)控件 + 自定义控件外观
- 在PC环境下用OPENGL做一个不断旋转和由小到大变化的五彩立方体
- Android UI控件之Gallery --拖动、覆盖、循环、3D图片浏览 效果之一
- ANDROID实现圆形图形不断旋转的动画
- android - 自定义(组合)控件 + 自定义控件外观
- android自定义控件(五) 自定义组合控件
- android自定义控件后如何调整自身子控件与父类中子控件的布局
- LoadingCircle 旋转线条Loading控件 循环 步进
- android控件xml属性解释(不断更新)
- Android利用RotateAnimation实现旋转变化动画
- Android gallery实现图片的左右循环旋转源码分享
- 转载 Android gallery实现图片的左右循环旋转
- android - 自定义(组合)控件 + 自定义控件外观
- android 控件 3d 旋转效果
- Android UI控件之Gallery --拖动、覆盖、循环、3D图片浏览 效果之一