android自定义View之(四)------一键清除动画

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>

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.参考资料:

1.Android自定义View实现雷达扫描动画

http://blog.csdn.net/oxygen0106/article/details/40144781

2.利用Android自定义View实现转盘旋转的效果

http://blog.csdn.net/canchew/article/details/5633421

时间: 2024-08-06 20:05:31

android自定义View之(四)------一键清除动画的相关文章

Android自定义view教程04-------------自定义属性动画

不太会美工,所以随便写了个菜单打开关闭的动画,主要是教会大家如何使用属性动画,可以这么说 学会属性动画 前面的fream动画和tween动画可以不用看了,因为他们2能做的,属性动画也能做, 他们2不能做的,属性动画也能做. 直接上代码吧,注释写的还算详细. 主activity代码 实际上没啥好看的,主要就是使用了dialogfragment,没有用dialog,因为谷歌后来推荐 我们使用这个dialogfragment,而且这个确实比dialog要优秀方便很多. package com.exam

Android自定义view教程01-------------Android的Frame动画详解

本系列博文 最终的目的是能教会大家自己实现比较复杂的android 自定义控件.所以知识点不仅仅局促在自定义view本身上面.实际上现在github上一些做的比较出色的自定义控件 大部分都是由三个部分组成 第一:动画 第二:自定义view 第三:触摸滑动控制.所以我们这个系列也是由动画作为开篇.最终会带着大家分析几个github上比较出色的自定义控件. Android 的frame动画是比较简单基础的内容,在以往的2.x 3.x版本很多人都会去使用这个 来作为loading 图的实现方法.但是最

Android自定义View绘图实现拖影动画

前几天在"Android绘图之渐隐动画"一文中通过画线实现了渐隐动画,但里面有个问题,画笔较粗(大于1)时线段之间会有裂隙,我又改进了一下.这次效果好多了. 先看效果吧: 然后我们来说说基本的做法: 根据画笔宽度,计算每一条线段两个顶点对应的四个点,四点连线,包围线段,形成一个路径. 后一条线段的路径的前两个点,取(等于)前一条线段的后两点,这样就衔接起来了. 把Path的Style修改为FILL,效果是这样的: 可以看到一个个四边形,连成了路径. 好啦,现在说说怎样根据两点计算出包围

Android 自定义View (五)&mdash;&mdash;实践

前言: 前面已经介绍了<Android 自定义 view(四)-- onMeasure 方法理解>,那么这次我们就来小实践下吧 任务: 公司现有两个任务需要我完成 (1)监测液化天然气液压罐的液位 (2)监测液化天然气液压罐的压力 UI设计师给我的设计截图如下:   任务一实践开始 第一步:先来看看整体结构组成 第二步:绘制文字 (1)我们将底部的文字.颜色,大小都是可以灵活自定义的,所以先得申明底部文字相关属性参数,方便根据需求进行设置 (2)整体上来看各个区域的颜色,文字画笔的相关属性都是

【Android自定义View实战】之仿百度加载动画,一种优雅的Loading方式

转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53470872 本文出自[DylanAndroid的博客] Android自定义View实战之仿百度加载动画一种优雅的Loading方式 第一个仿百度加载动画用ObjectAnimator属性动画操作ImageView的属性方法实现 第二个仿百度加载动画第二种实现方式用ValueAnimator原生的ondraw方法实现 第三个扔球动画-水平旋转动画 第四个扔球动画-垂直旋转动

Android 自定义View 四个构造函数详解

https://blog.csdn.net/zhao123h/article/details/52210732 在开发android开发过程中,很多人都会遇到自定义view,一般都需要继承自View类,而当你打开View类的源码时,发现会有四个构造函数,那么这四个构造函数是如何使用的呢,怎么合理的利用四个构造函数呢,本文将进行一定探究,希望能够抛砖引玉. 一 View类的四个构造函数先从android源码中把四个构造函数拉出来看看.. 1 第一个构造函数/** * Simple construc

【朝花夕拾】Android自定义View篇之(六)Android事件分发机制(中)从源码分析事件分发逻辑及经常遇到的一些“诡异”现象

前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/11039252.html]谢谢! 在上一篇文章[[朝花夕拾]Android自定义View篇之(五)Android事件分发机制(上)Touch三个重要方法的处理逻辑][下文简称(五),请先阅读完(五)再阅读本文],我们通过示例和log来分析了Android的事件分发机制.这些,我们只是看到了现象,如果要进一步了解事件分发机制,这是不够的,我们还需要透过现象看本质,去研究研究源码.本文将从源码(基

[原] Android 自定义View步骤

例子如下:Android 自定义View 密码框 例子 1 良好的自定义View 易用,标准,开放. 一个设计良好的自定义view和其他设计良好的类很像.封装了某个具有易用性接口的功能组合,这些功能能够有效地使用CPU和内存,并且十分开放的.但是,除了开始一个设计良好的类之外,一个自定义view应该: l 符合安卓标准 l 提供能够在Android XML布局中工作的自定义样式属性 l 发送可访问的事件 l 与多个Android平台兼容. Android框架提供了一套基本的类和XML标签来帮您创

Android自定义View(RollWeekView-炫酷的星期日期选择控件)

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/53420889 本文出自:[openXu的博客] 目录: 1分析 2定义控件布局 3定义CustomWeekView 4重写onMeasure 5点击后执行动画 7重置预备控件 源码下载 ??最近收到一个自定义控件的需求,需要做一个日期选择控件,实现图如下: ???? ??一次展示一个星期的5天,中间放大的为当前选中的:如果点击了其中一个日期,比如星期五,那么整体向左滑动,并将星期五慢慢放大