博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义控件 --- 加载旋转图标
阅读量:7041 次
发布时间:2019-06-28

本文共 8960 字,大约阅读时间需要 29 分钟。

      

1 import android.annotation.TargetApi;  2 import android.content.Context;  3 import android.content.res.Resources;  4 import android.content.res.TypedArray;  5 import android.graphics.Canvas;  6 import android.graphics.Paint;  7 import android.graphics.RectF;  8 import android.os.Build;  9 import android.util.AttributeSet; 10 import android.view.View; 11  12 /** 13  * 类似螺纹的加载view 14  * 可以自定义的属性:颜色、旋转速度(X弧度/s) 15  */ 16 public class WhorlView extends View { 17     private static final int CIRCLE_NUM = 3; 18  19     public static final int FAST = 1; 20     public static final int MEDIUM = 0; 21     public static final int SLOW = 2; 22  23     private static final int PARALLAX_FAST = 60; 24     private static final int PARALLAX_MEDIUM = 72; 25     private static final int PARALLAX_SLOW = 90; 26  27     private static final float SWEEP_ANGLE = 90f; 28     private static final float STOKE_WIDTH = 5f; 29     private static final long REFRESH_DURATION = 16L; 30  31     private long mCircleTime; 32     private int[] mLayerColors = new int[CIRCLE_NUM]; 33     private int mCircleSpeed; 34     private int mParallaxSpeed; 35  36     public WhorlView(Context context) { 37         this(context, null, 0); 38     } 39  40     public WhorlView(Context context, AttributeSet attrs) { 41         this(context, attrs, 0); 42     } 43  44     public WhorlView(Context context, AttributeSet attrs, int defStyleAttr) { 45         super(context, attrs, defStyleAttr); 46         Resources res = getResources(); 47         final int defaultSmallColor = res.getColor(R.color.material_red); 48         final int defaultMiddleColor = res.getColor(R.color.material_green); 49         final int defaultBigColor = res.getColor(R.color.material_blue); 50         //默认外层最慢180度/s 51         final int defaultCircleSpeed = 270; 52         if (attrs != null) { 53             final TypedArray typedArray = context.obtainStyledAttributes( 54                     attrs, R.styleable.WhorlView_Style); 55          mLayerColors[0] = typedArray.getColor(R.styleable.WhorlView_Style_WhorlView_SmallWhorlColor, defaultSmallColor); 56             mLayerColors[1] = typedArray.getColor(R.styleable.WhorlView_Style_WhorlView_MiddleWhorlColor, defaultMiddleColor); 57             mLayerColors[2] = typedArray.getColor(R.styleable.WhorlView_Style_WhorlView_BigWhorlColor, defaultBigColor); 58             mCircleSpeed = typedArray.getInt(R.styleable.WhorlView_Style_WhorlView_CircleSpeed, defaultCircleSpeed); 59             int index = typedArray.getInt(R.styleable.WhorlView_Style_WhorlView_Parallax, 0); 60             setParallax(index); 61             typedArray.recycle(); 62         } else { 63             mLayerColors[0] = defaultSmallColor; 64             mLayerColors[1] = defaultMiddleColor; 65             mLayerColors[2] = defaultBigColor; 66             mCircleSpeed = defaultCircleSpeed; 67             mParallaxSpeed = PARALLAX_MEDIUM; 68         } 69     } 70  72     private void setParallax(int index) { 73         switch (index) { 74             case FAST: 75                 mParallaxSpeed = PARALLAX_FAST; 76                 break; 77             case MEDIUM: 78                 mParallaxSpeed = PARALLAX_MEDIUM; 79                 break; 80             case SLOW: 81                 mParallaxSpeed = PARALLAX_SLOW; 82                 break; 83             default: 84                 throw new IllegalStateException("no such parallax type"); 85         } 86     } 87  88     @Override 89     protected void onDraw(Canvas canvas) { 90         super.onDraw(canvas); 91         for (int i = 0; i < CIRCLE_NUM; i++) { 92             float angle = (mCircleSpeed + mParallaxSpeed * (CIRCLE_NUM - i - 1)) * mCircleTime * 0.001f; 93             drawArc(canvas, i, angle); 94         } 95     } 96  97     private boolean mIsCircling = false; 98  99     /**100      * 旋转开始 
<功能简述>
101 */102 public void start() {103 mIsCircling = true;104 new Thread(new Runnable() {105 106 @Override107 public void run() {108 mCircleTime = 0L;109 while (mIsCircling) {110 invalidateWrap();111 mCircleTime = mCircleTime + REFRESH_DURATION;112 try {113 Thread.sleep(REFRESH_DURATION);114 } catch (InterruptedException e) {115 e.printStackTrace();116 }117 }118 }119 }).start();120 }121 122 public void stop() {123 mIsCircling = false;124 mCircleTime = 0L;125 invalidateWrap();126 }127 128 public boolean isCircling(){129 return mIsCircling;130 }131 132 @TargetApi(Build.VERSION_CODES.JELLY_BEAN)133 private void invalidateWrap() {134 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {135 postInvalidateOnAnimation();136 } else {137 postInvalidate();138 }139 }140 141 /**142 * 画弧143 *144 * @param canvas145 * @param index 由内而外146 * @param startAngle147 */148 private void drawArc(Canvas canvas, int index, float startAngle) {149 Paint paint = checkArcPaint(index);150 //最大圆是view的边界151 RectF oval = checkRectF(calcuRadiusRatio(index));152 canvas.drawArc(oval, startAngle, SWEEP_ANGLE, false, paint);153 }154 155 private Paint mArcPaint;156 157 private Paint checkArcPaint(int index) {158 if (mArcPaint == null) {159 mArcPaint = new Paint();160 } else {161 mArcPaint.reset();162 }163 mArcPaint.setColor(mLayerColors[index]);164 mArcPaint.setStyle(Paint.Style.STROKE);165 mArcPaint.setStrokeWidth(STOKE_WIDTH);166 mArcPaint.setAntiAlias(true);167 return mArcPaint;168 }169 170 private RectF mOval;171 172 private RectF checkRectF(float radiusRatio) {173 if (mOval == null) {174 mOval = new RectF();175 }176 float start = getMinLength() * 0.5f * (1 - radiusRatio) + STOKE_WIDTH;177 float end = getMinLength() - start;178 mOval.set(start, start, end, end);179 return mOval;180 }181 182 private static final float RADIUS_RATIO_P = 0.2f;183 184 /**185 * 计算每一圈的半径比例186 *187 * @param index188 * @return189 */190 private float calcuRadiusRatio(int index) {191 return 1f - (CIRCLE_NUM - index - 1) * RADIUS_RATIO_P;192 }193 194 private int getMinLength() {195 return Math.min(getWidth(), getHeight());196 }197 198 @Override199 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {200 int minSize = (int) (STOKE_WIDTH * 4 * CIRCLE_NUM);201 int wantSize = (int) (STOKE_WIDTH * 8 * CIRCLE_NUM);202 int size = measureSize(widthMeasureSpec, wantSize, minSize);203 setMeasuredDimension(size, size);204 }205 206 /**207 * 测量view的宽高208 *209 * @param measureSpec210 * @param wantSize211 * @param minSize212 * @return213 */214 public static int measureSize(int measureSpec, int wantSize, int minSize) {215 int result = 0;216 int specMode = MeasureSpec.getMode(measureSpec);217 int specSize = MeasureSpec.getSize(measureSpec);218 219 if (specMode == MeasureSpec.EXACTLY) {220 // 父布局想要view的大小221 result = specSize;222 } else {223 result = wantSize;224 if (specMode == MeasureSpec.AT_MOST) {225 // wrap_content226 result = Math.min(result, specSize);227 }228 }229 //测量的尺寸和最小尺寸取大230 return Math.max(result, minSize);231 }232 }

values/attrs.xml

1 
2
3
4
5
6
7
8
9
10
11
12
13
14

 

以上是自定义控件代码和资源文件。下面是如何使用自定义控件。

1 public class MainActivity extends Activity { 2     @Override 3     protected void onCreate(Bundle savedInstanceState) { 4         super.onCreate(savedInstanceState); 5         setContentView(R.layout.activity_main); 6         final WhorlView whorlView = (WhorlView) this.findViewById(R.id.whorl); 8         whorlView.setOnClickListener(new View.OnClickListener() { 9             @Override10             public void onClick(View v) {11                 if (whorlView.isCircling()) {12                     whorlView.stop();13                 } else {14                     whorlView.start();15                 }16             }17         });18     }19 }

values/color.xml

1 
2
3
#F44336
4
#4CAF50
5
#5677fc
6

 

转载地址:http://ndhal.baihongyu.com/

你可能感兴趣的文章
35 个 Java 代码性能优化总结
查看>>
理解Android安全机制
查看>>
从代码构建到性能分析,Java开发人员的首选工具
查看>>
如何防止rogue server破坏数据中心
查看>>
传网络安全提供商FireEye有意收购CyberArk
查看>>
手把手教你打造一个纯CSS图标库
查看>>
硬件辅助超融合:任意云中的全闪存VSAN
查看>>
个人隐私安全该何去何从-大量APP秘密收集追踪个人信息
查看>>
阿里云E-MapReduce 作业结果和日志查看
查看>>
智能路由器和普通路由器之间的区别有哪些
查看>>
2016 年上半年焦点信息安全事件盘点:要想好好上个网,容易嘛我!
查看>>
Kubernetes 火了!是时候扒一扒它的身世了
查看>>
国内大数据产业加速 2016年核心产业规模达到168亿元
查看>>
《资本说》极客帮创始人蒋涛(一)
查看>>
云计算世界里 新型IT思维应围绕业务展开
查看>>
全球最高海拔“逆”“变”一体化光伏电站一次性成功并网
查看>>
杭州中天微系统加入全球半导体联盟
查看>>
WiFi步入60GHz时代:助力4K、VR和物联网
查看>>
借助雨滴也能发电:功率转化效率85% 可与太阳能发电互补
查看>>
此刻, 演进到100G真不是梦
查看>>