Andorid 自定義 類似iOS活動指示器 UIActivityIndicatorView
由于個人喜好, 比較喜歡iOS 原生的東西,現(xiàn)在學(xué)習(xí)Android開發(fā),可能有先入為主的思想吧,所以總想在Andorid中找與iOS相同的控件。
在使用活動指示器的時候,發(fā)現(xiàn)Android的是ProgressBar,動畫的方式與iOS的不一樣,一直都想弄一個一樣的。
我自己比較喜歡自定義View,不是太喜歡GIF,雖然GIF方便,但學(xué)習(xí)嘛,空余時間多讓腦筋轉(zhuǎn)轉(zhuǎn)動動手也好。
這里就自定義一個iOS “菊花”式的活動指示器,
詳細代碼如下:
UIAcivityIndicatorView.java
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by wantao on 17/1/7.
*/
public class UIActivityIndicatorView extends View {
public UIActivityIndicatorView(Context context) {
this(context, null);
}
private int startColor = Color.argb(255, 255, 255, 255);
private float strokeWidth = 0;
private int startAngle = 0;
public UIActivityIndicatorView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.UIActivityIndicatorView);
for (int i = 0; i < typedArray.getIndexCount(); i++) {
int i1 = typedArray.getIndex(i);
if (i1 == R.styleable.UIActivityIndicatorView_AIV_startColor) {
startColor = typedArray.getColor(R.styleable.UIActivityIndicatorView_AIV_startColor, startColor);
} else if (i1 == R.styleable.UIActivityIndicatorView_AIV_startAngle) {
startAngle = typedArray.getInt(R.styleable.UIActivityIndicatorView_AIV_startAngle, startAngle);
} else if (i1 == R.styleable.UIActivityIndicatorView_AIV_strokeWidth) {
strokeWidth = typedArray.getDimension(R.styleable.UIActivityIndicatorView_AIV_strokeWidth, strokeWidth);
}
}
initialize();
}
private final int LineCount = 12;
private final int MinAlpha = 0;
private final int AngleGradient = 360 / LineCount;
private Paint paint;
private int[] colors = new int[LineCount];
private void initialize() {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
int alpha = Color.alpha(startColor);
int red = Color.red(startColor);
int green = Color.green(startColor);
int blue = Color.blue(startColor);
int alpha_gradient = Math.abs(alpha - MinAlpha) / LineCount;
for (int i = 0; i < colors.length; i++) {
colors[i] = Color.argb(alpha - alpha_gradient * i, red, green, blue);
}
paint.setStrokeCap(Paint.Cap.ROUND);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int centerX = getWidth()/2;
int centerY = getHeight()/2;
float radius = Math.min(getWidth()-getPaddingLeft()-getPaddingRight(), getHeight()-getPaddingTop()-getPaddingBottom()) * 0.5f;
if (strokeWidth == 0) strokeWidth = pointX(AngleGradient/2, radius/2)/2;
paint.setStrokeWidth(strokeWidth);
for (int i = 0; i < colors.length; i++) {
paint.setColor(colors[i]);
canvas.drawLine(
centerX + pointX(-AngleGradient*i + startAngle, radius/2),
centerY + pointY(-AngleGradient*i + startAngle, radius/2),
centerX + pointX(-AngleGradient*i + startAngle, radius - strokeWidth/2), // 這里計算Y值時, 之所以減去線寬/2, 是防止沒有設(shè)置的Padding時,圖像會超出View范圍
centerY + pointY(-AngleGradient*i + startAngle, radius - strokeWidth/2), // 這里計算Y值時, 之所以減去線寬/2, 是防止沒有設(shè)置的Padding時,圖像會超出View范圍
paint);
}
}
private float pointX(int angle, float radius) {
return (float) (radius * Math.cos(angle * Math.PI / 180));
}
private float pointY(int angle, float radius) {
return (float) (radius * Math.sin(angle * Math.PI / 180));
}
private Handler animHandler = new Handler();
private Runnable animRunnable = new Runnable() {
@Override
public void run() {
startAngle += AngleGradient;
invalidate();
animHandler.postDelayed(animRunnable, 50);
}
};
public void start() {
animHandler.post(animRunnable);
}
public void stop() {
animHandler.removeCallbacks(animRunnable);
}
public void setStartColor(int startColor) {
this.startColor = startColor;
}
public void setStrokeWidth(float strokeWidth) {
this.strokeWidth = strokeWidth;
}
public void setStartAngle(int startAngle) {
this.startAngle = startAngle;
}
}
自定義xml屬性文件, app→res→values→attrs.xml(這個xml文件沒有的話,自己新建一個)內(nèi)添加內(nèi)容如下:
另外,我還打包了一個“.aar”包,導(dǎo)入項目后可直接使用。
文件地址,還沒有審核通過,等通過后再更新,或者可以到我的資源頁查看。
對于怎么導(dǎo)入“.aar”包到項目,這里簡單介紹,【針對Android Studio(因為我也剛學(xué)習(xí)Andorid,只用過Android Studio)】:
1. 將需要的.aar文件拷貝到Project的app→libs中; 2. 修改build.grade(Module:app): 添加?repositories {
flatDir {
dirs 'libs'
}
}
然后在下面的dependencies(){}中添加
compile(name:'(.aar文件名)', ext:'aar')