更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680

1.前言:

  1. 本文采用自定义view的方法来实现一键清除的动画这个功能。

2.效果图:

 
 

3.具体详细代码

3.1 \res\values\attrs_on_key_clear_circle_view.xml

  1. <resources>
  2. <declare-styleable name="OnKeyClearCircleView">
  3. <attr name="innerCircleColor" format="color" />
  4. <attr name="outCircleColor" format="color" />
  5. <attr name="innerCircleRadius" format="integer" />
  6. <attr name="progress" format="integer" />
  7. <attr name="textSize" format="dimension" />
  8. <attr name="outArcwidth" format="dimension" />
  9. </declare-styleable>
  10. </resources>

对属性的说明:

  1. 一般,我们在res/values文件夹中添加attrs.xml文件来放置,其实,这个文件名并不一定要写成attrs.xml,但是按照安卓源码的写法并且也便于别人查看代码的时候明确这个文件的用意,还是写成attrs.xml
  2. 我们可以参看一下安卓的源码:打开源码文件夹下\frameworks\base\core\res\res\values\attrs.xml文件,我们会发现这里面定义了很多attr的标签,下面是我从这里面找到的一些:

  1. <attr name="buttonBarStyle" format="reference" />
  2. <attr name="cacheColorHint" format="color" />
  3. <attr name="textColorHint" format="reference|color" />
  4. <attr name="textIsSelectable" format="boolean" />
  5. <attr name="scrollbarFadeDuration" format="integer" />
  6. <attr name="alpha" format="float" />
  7. <attr name="textSize" format="dimension" />
  8. <attr name="columnDelay" format="float|fraction" />
  9. <attr name="fontFamily" format="string" />
  10. <!-- Default text typeface. -->
  11. <attr name="typeface">
  12. <enum name="normal" value="0" />
  13. <enum name="sans" value="1" />
  14. <enum name="serif" value="2" />
  15. <enum name="monospace" value="3" />
  16. </attr>
  17. <!-- Default text typeface style. -->
  18. <attr name="textStyle">
  19. <flag name="normal" value="0" />
  20. <flag name="bold" value="1" />
  21. <flag name="italic" value="2" />
  22. </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: 位或运算

写法样例:

  1. <declare-styleable name="TextViewMultiLineBackgroundState">
  2. <!-- State identifier indicating a TextView has a multi-line layout. -->
  3. <attr name="state_multiline" format="boolean" />
  4. </declare-styleable>

3.2 OnKeyClearCircleView.java

  1. import android.content.Context;
  2. import android.content.res.TypedArray;
  3. import android.graphics.Bitmap;
  4. import android.graphics.BitmapFactory;
  5. import android.graphics.Canvas;
  6. import android.graphics.Color;
  7. import android.graphics.Matrix;
  8. import android.graphics.Paint;
  9. import android.graphics.RectF;
  10. import android.graphics.SweepGradient;
  11. import android.util.AttributeSet;
  12. import android.util.Log;
  13. import android.view.View;
  14. import com.example.administrator.customview.R;
  15. public class OnKeyClearCircleView extends View implements Runnable{
  16. private static final String TAG = "OnKeyClearCircleView";
  17. private Paint paint;
  18. private Paint outCirclePaint;
  19. private Paint textPaint;
  20. private Paint outArcPaint;
  21. private Paint radarPain;
  22. private Paint pointPain;
  23. private int radarRotateDegree;
  24. private int innerCircleColor;
  25. private int innerCircleRadius;
  26. private int outCircleColor;
  27. private float outArcwidth;
  28. private SweepGradient outArcSweepGradient;
  29. private SweepGradient radarSweepGradient;
  30. private Bitmap pointDrawable;
  31. private Matrix pointRotate=new Matrix();
  32. private int progress;
  33. private float textSize;
  34. private int padding;
  35. private float startAngle;
  36. private float radarSweepAngle;
  37. private float pointRotateDegree;
  38. private boolean isSart;
  39. public OnKeyClearCircleView(Context context) {
  40. super(context);
  41. init(null, 0);
  42. }
  43. public OnKeyClearCircleView(Context context, AttributeSet attrs) {
  44. super(context, attrs);
  45. init(attrs, 0);
  46. }
  47. public OnKeyClearCircleView(Context context, AttributeSet attrs, int defStyle) {
  48. super(context, attrs, defStyle);
  49. init(attrs, defStyle);
  50. }
  51. private void init(AttributeSet attrs, int defStyle) {
  52. final TypedArray a = getContext().obtainStyledAttributes(
  53. attrs, R.styleable.OnKeyClearCircleView, defStyle, 0);
  54. innerCircleColor = a.getColor(R.styleable.OnKeyClearCircleView_innerCircleColor, Color.BLUE);
  55. outCircleColor = a.getColor(R.styleable.OnKeyClearCircleView_outCircleColor, Color.GRAY);
  56. innerCircleRadius = a.getInt(R.styleable.OnKeyClearCircleView_innerCircleRadius, 10);
  57. progress = a.getInt(R.styleable.OnKeyClearCircleView_progress,0);
  58. textSize = a.getDimension(R.styleable.OnKeyClearCircleView_textSize, 20);
  59. outArcwidth = a.getDimension(R.styleable.OnKeyClearCircleView_outArcwidth, 20);
  60. a.recycle();
  61. pointDrawable = BitmapFactory.decodeResource(getResources(),R.drawable.point);
  62. isSart = false;
  63. startAngle = 0;
  64. radarRotateDegree = 0;
  65. radarSweepAngle = 0;
  66. pointRotateDegree = 0;
  67. padding = 5;
  68. paint = new Paint();
  69. paint.setAntiAlias(true);
  70. paint.setColor(innerCircleColor);
  71. outCirclePaint = new Paint();
  72. outCirclePaint.setAntiAlias(true);
  73. outCirclePaint.setColor(outCircleColor);
  74. outCirclePaint.setStyle(Paint.Style.FILL);
  75. textPaint = new Paint();
  76. textPaint.setTextSize(textSize);
  77. textPaint.setAntiAlias(true);
  78. outArcPaint = new Paint();
  79. outArcPaint.setAntiAlias(true);
  80. outArcPaint.setStyle(Paint.Style.STROKE);
  81. outArcPaint.setStrokeWidth(outArcwidth);
  82. outArcPaint.setStrokeCap(Paint.Cap.ROUND);
  83. radarPain = new Paint();
  84. outArcPaint.setAntiAlias(true);
  85. pointPain = new Paint();
  86. pointPain.setAntiAlias(true);
  87. Thread thread=new Thread(this);
  88. thread.start();
  89. }
  90. @Override
  91. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  92. //super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  93. int width = MeasureSpec.getSize(widthMeasureSpec);
  94. int height = MeasureSpec.getSize(heightMeasureSpec);
  95. int d = (width >= height) ? height : width;
  96. setMeasuredDimension(d,d);
  97. }
  98. @Override
  99. protected void onDraw(Canvas canvas) {
  100. int width = getMeasuredWidth();
  101. int height = getMeasuredHeight();
  102. int pointX = width/2;
  103. int pointY = height/2;
  104. RectF rectf = new RectF(outArcwidth/2,outArcwidth/2,width-outArcwidth/2,height-outArcwidth/2);
  105. //outArcSweepGradient = new SweepGradient(0,0,getResources().getColor(R.color.start_color),getResources().getColor(R.color.end_color));
  106. outArcSweepGradient = new SweepGradient(pointX,pointY,Color.WHITE,Color.WHITE);
  107. outArcPaint.setShader(outArcSweepGradient);
  108. canvas.drawArc(rectf,startAngle,180,false,outArcPaint);
  109. canvas.drawCircle(pointX,pointY,pointX -outArcwidth-padding,outCirclePaint);
  110. if(radarSweepAngle < 180){
  111. radarSweepGradient = new SweepGradient(pointX,pointY,Color.WHITE,Color.RED);
  112. }else{
  113. radarSweepGradient = new SweepGradient(pointX,pointY,Color.WHITE,Color.GREEN);
  114. }
  115. radarPain.setShader(radarSweepGradient);
  116. RectF rectfRadar = new RectF(outArcwidth+padding,outArcwidth+padding,width-outArcwidth-padding,height-outArcwidth-padding);
  117. canvas.drawArc(rectfRadar,0,radarSweepAngle,true,radarPain);
  118. canvas.save();
  119. canvas.translate(pointX,pointY);
  120. pointRotate.setRotate(pointRotateDegree);
  121. canvas.drawBitmap(pointDrawable, pointRotate, pointPain);
  122. canvas.restore();;
  123. canvas.drawCircle(pointX,pointY,innerCircleRadius,paint);
  124. float textWidth = textPaint.measureText(progress + "%");
  125. if(progress < 50){
  126. //textPaint.setColor(oxbf3800);
  127. textPaint.setColor(Color.RED);
  128. }else{
  129. //textPaint.setColor(new Color(ox6ec705));
  130. textPaint.setColor(Color.GREEN);
  131. }
  132. canvas.drawText(progress+"%",pointX - textWidth/2,pointY + textSize/2 ,textPaint);
  133. }
  134. @Override
  135. public void run() {
  136. while(true){
  137. if(isSart){
  138. this.startAngle += 20;
  139. if(this.startAngle > 360){
  140. this.startAngle = this.startAngle-360;
  141. }
  142. this.radarSweepAngle += 10;
  143. if(this.radarSweepAngle > 360){
  144. this.radarSweepAngle = this.radarSweepAngle-360;
  145. }
  146. this.pointRotateDegree += 10;
  147. if(this.pointRotateDegree > 360){
  148. this.pointRotateDegree = this.pointRotateDegree-360;
  149. }
  150. progress = (int)radarSweepAngle*100/360;
  151. postInvalidate();
  152. try {
  153. Thread.sleep(50);
  154. } catch (InterruptedException e) {
  155. e.printStackTrace();
  156. }
  157. }
  158. }
  159. }
  160. public void startClear(){
  161. this.isSart = true;
  162. }
  163. public void stopClear(){
  164. this.isSart =false;
  165. }
  166. public int getProgress() {
  167. return progress;
  168. }
  169. public void setProgress(int progress) {
  170. this.progress = progress;
  171. }
  172. }

3.3 res\layout\activity_custom_view_activity4.xml

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
  6. android:paddingRight="@dimen/activity_horizontal_margin"
  7. android:paddingTop="@dimen/activity_vertical_margin"
  8. android:paddingBottom="@dimen/activity_vertical_margin"
  9. tools:context="com.example.administrator.customview.customview04.CustomViewActivity4">
  10. <com.example.administrator.customview.customview04.OnKeyClearCircleView
  11. android:layout_width="200dp"
  12. android:layout_height="200dp"
  13. android:id="@+id/onKeyClearCircleView"
  14. android:background="#fdda6f"
  15. app:innerCircleColor="#ffffff"
  16. app:innerCircleRadius="35"
  17. app:textSize="20sp"
  18. app:progress="82"
  19. app:outCircleColor="#dbdad7"
  20. app:outArcwidth="10dp"
  21. />
  22. <Button
  23. android:layout_width="wrap_content"
  24. android:layout_height="wrap_content"
  25. android:text="start"
  26. android:id="@+id/start"
  27. android:layout_below="@+id/onKeyClearCircleView"
  28. android:layout_alignParentLeft="true"
  29. android:layout_alignParentStart="true" />
  30. <Button
  31. android:layout_width="wrap_content"
  32. android:layout_height="wrap_content"
  33. android:text="end"
  34. android:id="@+id/end"
  35. android:layout_below="@+id/start"
  36. android:layout_alignParentLeft="true"
  37. android:layout_alignParentStart="true" />
  38. </RelativeLayout>

3.4 CustomViewActivity4.java

  1. [java] view plain copy
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.view.View;
  5. import android.widget.Button;
  6. import com.example.administrator.customview.R;
  7. public class CustomViewActivity4 extends Activity implements View.OnClickListener {
  8. private OnKeyClearCircleView onKeyClearCircleView;
  9. private Button start;
  10. private Button end;
  11. @Override
  12. protected void onCreate(Bundle savedInstanceState) {
  13. super.onCreate(savedInstanceState);
  14. setContentView(R.layout.activity_custom_view_activity4);
  15. init();
  16. }
  17. private void init() {
  18. onKeyClearCircleView = (OnKeyClearCircleView) findViewById(R.id.onKeyClearCircleView);
  19. start = (Button) findViewById(R.id.start);
  20. start.setOnClickListener(this);
  21. end = (Button) findViewById(R.id.end);
  22. end.setOnClickListener(this);
  23. }
  24. @Override
  25. public void onClick(View view) {
  26. if(view == start){
  27. onKeyClearCircleView.startClear();
  28. }else if(view == end){
  29. onKeyClearCircleView.stopClear();
  30. }
  31. }
  32. }

更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680

原文链接https://blog.csdn.net/hfreeman2008/article/details/43051425#

高级UI晋升之自定义View实战(九)的更多相关文章

  1. 高级UI晋升之自定义View实战(六)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从Android 自定义属性动画&Camera动画来介绍自定义V ...

  2. 高级UI晋升之自定义View实战(五)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从自定义View利器Canvas和Paint来进行详解 一.Canvas ...

  3. 高级UI晋升之自定义view实战(七)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章自定义ViewGroup实现瀑布流效果来进行详解dispatchTouch ...

  4. 高级UI晋升之自定义View实战(八)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章自定义流式布局来进行介绍: 一般常见的流式布局由两种,一种是横向的个数固定 ...

  5. 高级UI晋升之常用View(三)中篇

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从ViewPager来介绍常用View:文章目录 一.简介 二.基本使用 ...

  6. 高级UI晋升之常用View(三)上篇

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将先从以下两个内容来介绍常用View: [RecycleView] [Ca ...

  7. 高级UI晋升之常用View(三)下篇

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从WebView来介绍常用View: 一.WebView介绍 Andro ...

  8. 高级UI晋升之View渲染机制(二)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 优化性能一般从渲染,运算与内存,电量三个方面进行,今天开始说聊一聊Android ...

  9. Android自定义View实战(SlideTab-可滑动的选择器)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/52178553 本文出自:[openXu的博客] 目录: 初步分析重写onDraw绘制 重写o ...

随机推荐

  1. 后台获取html控件的值

    string name = Request.Form["Name1"].ToString(); “xxx” 里的是name值 Request["xx"]取到相同 ...

  2. Cocos2d-x之Log输出机制

    |   版权声明:本文为博主原创文章,未经博主允许不得转载. 在cocos2d-x中,我们使用log这个函数进行输出,log可以输出很多参数,它的使用方式就和使用c语言中的printf的使用方式差不多 ...

  3. 最小,独立,可分发的跨平台Web服务器

    最近,我一直在编写大量较小的wsgi应用程序,并希望找到一个可以分布式,预先配置为运行特定应用程序的Web服务器.我知道有些东西可以用于wsgi应用程序,例如twisted和cherrypy,但它们似 ...

  4. c# WPF DataGrid 获取选中单元格信息

    private void Dg_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e) { Console.Write ...

  5. C#反射的实现

    一,什么是反射? 1,System.Reflection 命名空间中的类与 System.Type 使你能够获取有关加载的程序集和其中定义的类型的信息,如类.接口和值类型. 可以使用反射在运行时创建. ...

  6. WTSEnumerateSessions 枚举session信息

    http://dwbpriarie.lofter.com/post/1cd339fc_8cf728c https://www.cnblogs.com/priarieNew/p/9755655.html ...

  7. 六、SpringBoot配置@ConfigurationProperties与@Value区别

    1.@Value的使用 三种用法 // ${key} 从环境变量.配置文件中取值 @Value("${person.last-name}") private String last ...

  8. Elasticsearch index

    POST/{index}/{type} Elasticsearch自动生成ID,自动生成的 ID 是 URL-safe. 基于 Base64 编码且长度为20个字符的 GUID 字符串. 这些 GUI ...

  9. HTML+CSS+JS是什么

    html:整合网页结构和内容显示的一种语言 css:是一种用来表现HTML或XML等文件样式的计算机语言 js:增加表现力的脚本 做网页前台设计的标准套装,html是一些网页控件,css是美化这些控件 ...

  10. 割点的tarjan算法模板

    基本思路: 朴素的思想是删除每一个点,然后去dfs,这样无疑会爆炸 换一种思路,怎样判断是割点呢,如果是根节点的话毫无疑问只要看子树的数目,但是如果不是根节点呢,不知大牛是怎样想到的 利用两个数组df ...