android5.0风格兼容3.0以下版本炫酷加载圈

android3.0以下系统的加载圈很丑,影响APP美观,所以找了一个向下兼容5.0风格的加载圈,还可以自定义颜色,效果很棒。

首先是CustomView,自定义View的基类

package xking.com.kingcircularindeterminatepb.views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.widget.RelativeLayout;

public class CustomView extends RelativeLayout{
	
	
	final static String MATERIALDESIGNXML = "http://schemas.android.com/apk/res-auto";
	final static String ANDROIDXML = "http://schemas.android.com/apk/res/android";
	
	final int disabledBackgroundColor = Color.parseColor("#E2E2E2");
	int beforeBackground;
	
	// Indicate if user touched this view the last time
	public boolean isLastTouch = false;

	public CustomView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
	
	@Override
	public void setEnabled(boolean enabled) {
		super.setEnabled(enabled);
		if(enabled)
			setBackgroundColor(beforeBackground);
		else
			setBackgroundColor(disabledBackgroundColor);
		invalidate();
	}
	
	boolean animation = false;
	
	@Override
	protected void onAnimationStart() {
		super.onAnimationStart();
		animation = true;
	}
	
	@Override
	protected void onAnimationEnd() {
		super.onAnimationEnd();
		animation = false;
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		if(animation)
			invalidate();
	}
}
接下来就是重点,自定义加载圈代码

package xking.com.kingcircularindeterminatepb.views;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.AttributeSet;

import xking.com.kingcircularindeterminatepb.utils.Utils;

public class ProgressBarCircularIndeterminate extends CustomView {
	
	
	final static String ANDROIDXML = "http://schemas.android.com/apk/res/android";
	
	int backgroundColor = Color.parseColor("#1E88E5");
	

	public ProgressBarCircularIndeterminate(Context context, AttributeSet attrs) {
		super(context, attrs);
		setAttributes(attrs);
		
	}
	
	// Set atributtes of XML to View
		protected void setAttributes(AttributeSet attrs){
			
			setMinimumHeight(Utils.dpToPx(32, getResources()));
			setMinimumWidth(Utils.dpToPx(32, getResources()));
			
			//Set background Color
			// Color by resource
			int bacgroundColor = attrs.getAttributeResourceValue(ANDROIDXML,"background",-1);
			if(bacgroundColor != -1){
				setBackgroundColor(getResources().getColor(bacgroundColor));
			}else{
				// Color by hexadecimal
				int background = attrs.getAttributeIntValue(ANDROIDXML, "background", -1);
				if (background != -1)
					setBackgroundColor(background);
				else
					setBackgroundColor(Color.parseColor("#1E88E5"));
			}
			
			setMinimumHeight(Utils.dpToPx(3, getResources()));
			
						
		}
	
	/**
	 * Make a dark color to ripple effect
	 * @return
	 */
	protected int makePressColor(){
		int r = (this.backgroundColor >> 16) & 0xFF;
		int g = (this.backgroundColor >> 8) & 0xFF;
		int b = (this.backgroundColor >> 0) & 0xFF;
//		r = (r+90 > 245) ? 245 : r+90;
//		g = (g+90 > 245) ? 245 : g+90;
//		b = (b+90 > 245) ? 245 : b+90;
		return Color.argb(128,r, g, b);		
	}
	
	
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		if(firstAnimationOver == false)
			drawFirstAnimation(canvas);
		if(cont > 0)
			drawSecondAnimation(canvas);
		invalidate();
		
	}
	
	float radius1 = 0;
	float radius2 = 0;
	int cont = 0;
	boolean firstAnimationOver = false;
	/**
	 * Draw first animation of view
	 * @param canvas
	 */
	private void drawFirstAnimation(Canvas canvas){
		if(radius1 < getWidth()/2){
			Paint paint = new Paint();
			paint.setAntiAlias(true);
			paint.setColor(makePressColor());
			radius1 = (radius1 >= getWidth()/2)? (float)getWidth()/2 : radius1+1;
			canvas.drawCircle(getWidth()/2, getHeight()/2, radius1, paint);
		}else{
			Bitmap bitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
		    Canvas temp = new Canvas(bitmap);
		    Paint paint = new Paint();
			paint.setAntiAlias(true);
			paint.setColor(makePressColor());
			temp.drawCircle(getWidth()/2, getHeight()/2, getHeight()/2, paint);
		    Paint transparentPaint = new Paint();
		    transparentPaint.setAntiAlias(true);
		    transparentPaint.setColor(getResources().getColor(android.R.color.transparent));
		    transparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
		    if(cont >= 50){
		    	radius2 = (radius2 >= getWidth()/2)? (float)getWidth()/2 : radius2+1;
		    }else{
		    	radius2 = (radius2 >= getWidth()/2-Utils.dpToPx(4, getResources()))? (float)getWidth()/2-Utils.dpToPx(4, getResources()) : radius2+1;
		    }
		    temp.drawCircle(getWidth()/2, getHeight()/2, radius2, transparentPaint);
		    canvas.drawBitmap(bitmap, 0, 0, new Paint());
		    if(radius2 >= getWidth()/2-Utils.dpToPx(4, getResources()))
		    	cont++;
		    if(radius2 >= getWidth()/2)
		    	firstAnimationOver = true;
		}
	}
	
	int arcD = 1;
	int arcO = 0;
	float rotateAngle = 0;
	int limite = 0;
	/**
	 * Draw second animation of view
	 * @param canvas
	 */
	private void drawSecondAnimation(Canvas canvas){
		if(arcO == limite)
			arcD+=6;
		if(arcD >= 290 || arcO > limite){
			arcO+=6;
			arcD-=6;
		}
		if(arcO > limite + 290){
			limite = arcO;
			arcO = limite;
			arcD = 1;
		}
		rotateAngle += 4;
		canvas.rotate(rotateAngle,getWidth()/2, getHeight()/2);
		
	    Bitmap bitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
	    Canvas temp = new Canvas(bitmap);
	    Paint paint = new Paint();
		paint.setAntiAlias(true);
		paint.setColor(backgroundColor);
//		temp.drawARGB(0, 0, 0, 255);
		temp.drawArc(new RectF(0, 0, getWidth(), getHeight()), arcO, arcD, true, paint);
	    Paint transparentPaint = new Paint();
	    transparentPaint.setAntiAlias(true);
	    transparentPaint.setColor(getResources().getColor(android.R.color.transparent));
	    transparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
	    temp.drawCircle(getWidth()/2, getHeight()/2, (getWidth()/2)-Utils.dpToPx(4, getResources()), transparentPaint);

	    canvas.drawBitmap(bitmap, 0, 0, new Paint());
	}
	
	
	
	
	
	// Set color of background
	public void setBackgroundColor(int color){
		super.setBackgroundColor(getResources().getColor(android.R.color.transparent));
		if(isEnabled())
			beforeBackground = backgroundColor;
		this.backgroundColor = color;
	}

}
最后其中一个工具类,用来dx与dp的转换
package xking.com.kingcircularindeterminatepb.utils;

import android.content.res.Resources;
import android.util.TypedValue;
import android.view.View;

public class Utils {
	
	
	/**
	 * Convert Dp to Pixel
	 */
	public static int dpToPx(float dp, Resources resources){
		float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, resources.getDisplayMetrics());
		return (int) px;
	}

}
使用十分简单,直接在layout中添加

  <xking.com.kingcircularindeterminatepb.views.ProgressBarCircularIndeterminate
        android:id="@+id/progressBarCircularIndetermininate"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_centerInParent="true"
        android:background="@color/colorPrimary" />
效果如图

效果比较炫酷

附上demo点击打开链接

附上github地址 点击打开链接

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值