1.前言:
自己也是参考别人的一些自定义view例子,学习了一些基本的自定义view的方法。今天,我参考了一些资料,再结合自已的一些理解,做了一个一键清除的动画。当年,我实现这个是用了几张图片,采用Frame anination的方式来实现,但是这个方法,不灵活,并且占资源,下面,我就采用自定义view的方法来实现这个功能。
2.效果图:
3.具体详细代码
3.1 \res\values\attrs_on_key_clear_circle_view.xml
- <resources>
- <declare-styleable name="OnKeyClearCircleView">
- <attr name="innerCircleColor" format="color" />
- <attr name="outCircleColor" format="color" />
- <attr name="innerCircleRadius" format="integer" />
- <attr name="progress" format="integer" />
- <attr name="textSize" format="dimension" />
- <attr name="outArcwidth" format="dimension" />
- </declare-styleable>
- </resources>
对属性的说明:
一般,我们在res/values文件夹中添加attrs.xml文件来放置,其实,这个文件名并不一定要写成attrs.xml,但是按照安卓源码的写法并且也便于别人查看代码的时候明确这个文件的用意,还是写成attrs.xml。
我们可以参看一下安卓的源码:打开源码文件夹下\frameworks\base\core\res\res\values\attrs.xml文件,我们会发现这里面定义了很多attr的标签,下面是我从这里面找到的一些:
- <attr name="buttonBarStyle" format="reference" />
- <attr name="cacheColorHint" format="color" />
- <attr name="textColorHint" format="reference|color" />
- <attr name="textIsSelectable" format="boolean" />
- <attr name="scrollbarFadeDuration" format="integer" />
- <attr name="alpha" format="float" />
- <attr name="textSize" format="dimension" />
- <attr name="columnDelay" format="float|fraction" />
- <attr name="fontFamily" format="string" />
- <!-- Default text typeface. -->
- <attr name="typeface">
- <enum name="normal" value="0" />
- <enum name="sans" value="1" />
- <enum name="serif" value="2" />
- <enum name="monospace" value="3" />
- </attr>
- <!-- Default text typeface style. -->
- <attr name="textStyle">
- <flag name="normal" value="0" />
- <flag name="bold" value="1" />
- <flag name="italic" value="2" />
- </attr>
其中,format代表的是这条属性的值的类型:
1.reference: 参考指定Theme中资源ID,这个类型意思就是你传的值可以是引用资源
2.string: 字符 如果你想别人既能直接写值也可以用类似"@string/test"引用资源的方式,可以写成format="string|reference"
3.Color: 颜色
4.boolean: 布尔值
5.dimension: 尺寸值
6.float: 浮点型
7.integer: 整型
8.fraction: 百分数
9.enum: 枚举 ,如果你提供的属性只能让别人选择,不能随便传入,
10.flag: 位或运算
写法样例:
- <declare-styleable name="TextViewMultiLineBackgroundState">
- <!-- State identifier indicating a TextView has a multi-line layout. -->
- <attr name="state_multiline" format="boolean" />
- </declare-styleable>
3.2 OnKeyClearCircleView.java
- import android.content.Context;
- import android.content.res.TypedArray;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Matrix;
- import android.graphics.Paint;
- import android.graphics.RectF;
- import android.graphics.SweepGradient;
- import android.util.AttributeSet;
- import android.util.Log;
- import android.view.View;
- import com.example.administrator.customview.R;
- public class OnKeyClearCircleView extends View implements Runnable{
- private static final String TAG = "OnKeyClearCircleView";
- private Paint paint;
- private Paint outCirclePaint;
- private Paint textPaint;
- private Paint outArcPaint;
- private Paint radarPain;
- private Paint pointPain;
- private int radarRotateDegree;
- private int innerCircleColor;
- private int innerCircleRadius;
- private int outCircleColor;
- private float outArcwidth;
- private SweepGradient outArcSweepGradient;
- private SweepGradient radarSweepGradient;
- private Bitmap pointDrawable;
- private Matrix pointRotate=new Matrix();
- private int progress;
- private float textSize;
- private int padding;
- private float startAngle;
- private float radarSweepAngle;
- private float pointRotateDegree;
- private boolean isSart;
- public OnKeyClearCircleView(Context context) {
- super(context);
- init(null, 0);
- }
- public OnKeyClearCircleView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(attrs, 0);
- }
- public OnKeyClearCircleView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- init(attrs, defStyle);
- }
- private void init(AttributeSet attrs, int defStyle) {
- final TypedArray a = getContext().obtainStyledAttributes(
- attrs, R.styleable.OnKeyClearCircleView, defStyle, 0);
- innerCircleColor = a.getColor(R.styleable.OnKeyClearCircleView_innerCircleColor, Color.BLUE);
- outCircleColor = a.getColor(R.styleable.OnKeyClearCircleView_outCircleColor, Color.GRAY);
- innerCircleRadius = a.getInt(R.styleable.OnKeyClearCircleView_innerCircleRadius, 10);
- progress = a.getInt(R.styleable.OnKeyClearCircleView_progress,0);
- textSize = a.getDimension(R.styleable.OnKeyClearCircleView_textSize, 20);
- outArcwidth = a.getDimension(R.styleable.OnKeyClearCircleView_outArcwidth, 20);
- a.recycle();
- pointDrawable = BitmapFactory.decodeResource(getResources(),R.drawable.point);
- isSart = false;
- startAngle = 0;
- radarRotateDegree = 0;
- radarSweepAngle = 0;
- pointRotateDegree = 0;
- padding = 5;
- paint = new Paint();
- paint.setAntiAlias(true);
- paint.setColor(innerCircleColor);
- outCirclePaint = new Paint();
- outCirclePaint.setAntiAlias(true);
- outCirclePaint.setColor(outCircleColor);
- outCirclePaint.setStyle(Paint.Style.FILL);
- textPaint = new Paint();
- textPaint.setTextSize(textSize);
- textPaint.setAntiAlias(true);
- outArcPaint = new Paint();
- outArcPaint.setAntiAlias(true);
- outArcPaint.setStyle(Paint.Style.STROKE);
- outArcPaint.setStrokeWidth(outArcwidth);
- outArcPaint.setStrokeCap(Paint.Cap.ROUND);
- radarPain = new Paint();
- outArcPaint.setAntiAlias(true);
- pointPain = new Paint();
- pointPain.setAntiAlias(true);
- Thread thread=new Thread(this);
- thread.start();
- }
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- //super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- int width = MeasureSpec.getSize(widthMeasureSpec);
- int height = MeasureSpec.getSize(heightMeasureSpec);
- int d = (width >= height) ? height : width;
- setMeasuredDimension(d,d);
- }
- @Override
- protected void onDraw(Canvas canvas) {
- int width = getMeasuredWidth();
- int height = getMeasuredHeight();
- int pointX = width/2;
- int pointY = height/2;
- RectF rectf = new RectF(outArcwidth/2,outArcwidth/2,width-outArcwidth/2,height-outArcwidth/2);
- //outArcSweepGradient = new SweepGradient(0,0,getResources().getColor(R.color.start_color),getResources().getColor(R.color.end_color));
- outArcSweepGradient = new SweepGradient(pointX,pointY,Color.WHITE,Color.WHITE);
- outArcPaint.setShader(outArcSweepGradient);
- canvas.drawArc(rectf,startAngle,180,false,outArcPaint);
- canvas.drawCircle(pointX,pointY,pointX -outArcwidth-padding,outCirclePaint);
- if(radarSweepAngle < 180){
- radarSweepGradient = new SweepGradient(pointX,pointY,Color.WHITE,Color.RED);
- }else{
- radarSweepGradient = new SweepGradient(pointX,pointY,Color.WHITE,Color.GREEN);
- }
- radarPain.setShader(radarSweepGradient);
- RectF rectfRadar = new RectF(outArcwidth+padding,outArcwidth+padding,width-outArcwidth-padding,height-outArcwidth-padding);
- canvas.drawArc(rectfRadar,0,radarSweepAngle,true,radarPain);
- canvas.save();
- canvas.translate(pointX,pointY);
- pointRotate.setRotate(pointRotateDegree);
- canvas.drawBitmap(pointDrawable, pointRotate, pointPain);
- canvas.restore();;
- canvas.drawCircle(pointX,pointY,innerCircleRadius,paint);
- float textWidth = textPaint.measureText(progress + "%");
- if(progress < 50){
- //textPaint.setColor(oxbf3800);
- textPaint.setColor(Color.RED);
- }else{
- //textPaint.setColor(new Color(ox6ec705));
- textPaint.setColor(Color.GREEN);
- }
- canvas.drawText(progress+"%",pointX - textWidth/2,pointY + textSize/2 ,textPaint);
- }
- @Override
- public void run() {
- while(true){
- if(isSart){
- this.startAngle += 20;
- if(this.startAngle > 360){
- this.startAngle = this.startAngle-360;
- }
- this.radarSweepAngle += 10;
- if(this.radarSweepAngle > 360){
- this.radarSweepAngle = this.radarSweepAngle-360;
- }
- this.pointRotateDegree += 10;
- if(this.pointRotateDegree > 360){
- this.pointRotateDegree = this.pointRotateDegree-360;
- }
- progress = (int)radarSweepAngle*100/360;
- postInvalidate();
- try {
- Thread.sleep(50);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- public void startClear(){
- this.isSart = true;
- }
- public void stopClear(){
- this.isSart =false;
- }
- public int getProgress() {
- return progress;
- }
- public void setProgress(int progress) {
- this.progress = progress;
- }
- }
3.3 res\layout\activity_custom_view_activity4.xml
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- android:paddingBottom="@dimen/activity_vertical_margin"
- tools:context="com.example.administrator.customview.customview04.CustomViewActivity4">
- <com.example.administrator.customview.customview04.OnKeyClearCircleView
- android:layout_width="200dp"
- android:layout_height="200dp"
- android:id="@+id/onKeyClearCircleView"
- android:background="#fdda6f"
- app:innerCircleColor="#ffffff"
- app:innerCircleRadius="35"
- app:textSize="20sp"
- app:progress="82"
- app:outCircleColor="#dbdad7"
- app:outArcwidth="10dp"
- />
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="start"
- android:id="@+id/start"
- android:layout_below="@+id/onKeyClearCircleView"
- android:layout_alignParentLeft="true"
- android:layout_alignParentStart="true" />
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="end"
- android:id="@+id/end"
- android:layout_below="@+id/start"
- android:layout_alignParentLeft="true"
- android:layout_alignParentStart="true" />
- </RelativeLayout>
3.4 CustomViewActivity4.java
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
- import com.example.administrator.customview.R;
- public class CustomViewActivity4 extends Activity implements View.OnClickListener {
- private OnKeyClearCircleView onKeyClearCircleView;
- private Button start;
- private Button end;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_custom_view_activity4);
- init();
- }
- private void init() {
- onKeyClearCircleView = (OnKeyClearCircleView) findViewById(R.id.onKeyClearCircleView);
- start = (Button) findViewById(R.id.start);
- start.setOnClickListener(this);
- end = (Button) findViewById(R.id.end);
- end.setOnClickListener(this);
- }
- @Override
- public void onClick(View view) {
- if(view == start){
- onKeyClearCircleView.startClear();
- }else if(view == end){
- onKeyClearCircleView.stopClear();
- }
- }
- }
4.代码下载地址:
5.参考资料:
http://blog.csdn.net/oxygen0106/article/details/40144781
http://blog.csdn.net/canchew/article/details/5633421