載入圓形進度條
阿新 • • 發佈:2019-02-03
專案需求,需要類似於支付寶支付時的圓形進度條,主要效果是圓形有無到有,再變成由有到無,如果載入成功,則在有無到有結束的時候,顯示對號
具體效果圖:
類似的實現,在github上有一個開源專案,github,我下載下來,在原有程式碼的基礎上進行了修改
CusImage.java
public class CusImage extends View {
private Paint myPaint;
private Paint myFramePaint;
public TextView value;
private float startAngle;
public float temp;
float sweepAngle;
private int flag = 0;
RectF rect;
private MasterLayout m;
int pix = 0;
public boolean progressFlag = true;//兩種繪畫方式,由無到有為true,由有到無為false
public CusImage(Context context, AttributeSet attrs, MasterLayout m) {
super(context, attrs);
this .m = m;
init();
}
public CusImage(Context context, MasterLayout m) {
super(context);
this.m = m;
init();
}
private void init() {
myPaint = new Paint();
DisplayMetrics metrics = getContext().getResources()
.getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;
float scarea = width * height;
pix = (int) Math.sqrt(scarea * 0.07);
myPaint.setAntiAlias(true);
myPaint.setStyle(Paint.Style.STROKE);
myPaint.setColor(getResources().getColor(R.color.baseGreen)); // Edit this to change
// progress arc color.
myPaint.setStrokeWidth(15);
myFramePaint = new Paint();
myFramePaint.setAntiAlias(true);
myFramePaint.setColor(Color.TRANSPARENT);
float startx = (float) (pix * 0.05);
float endx = (float) (pix * 0.95);
float starty = (float) (pix * 0.05);
float endy = (float) (pix * 0.95);
rect = new RectF(startx, starty, endx, endy);
}
public void setupprogress(int progress) {
// Updating progress arc
sweepAngle = (float) (progress * 3.6);
//Log.e("sweepAngle", sweepAngle+"");
}
public void setupprogress2(int progress) {
// Updating progress arc
sweepAngle = (float) (progress * 3.6) - 360;
//Log.e("sweepAngle", sweepAngle+"");
}
public void reset() {
// Resetting progress arc
sweepAngle = 0;
startAngle = -90;
flag = 1;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int desiredWidth = pix;
int desiredHeight = pix;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
width = Math.min(desiredWidth, widthSize);
} else {
width = desiredWidth;
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
height = Math.min(desiredHeight, heightSize);
} else {
height = desiredHeight;
}
setMeasuredDimension(width, height);
}
@Override
protected void onDraw(Canvas canvas) {
/*if(progressFlag==1){
canvas.drawArc(rect, startAngle, sweepAngle, false, myPaint);
startAngle = -90;
invalidate();
else if (flag == 1) {
sweepAngle = 0;
startAngle = -90;
flag = 0;
invalidate();
} else {
reset();
invalidate();
sweepAngle = 0;
startAngle = -90;
m.finalAnimation();
}
}else{
canvas.drawArc(rect, startAngle, sweepAngle, false, myPaint);
sweepAngle = 270;
if (startAngle < 360 && flag == 0) {
invalidate();
} else {
reset();
invalidate();
sweepAngle = 0;
startAngle = -90;
m.finalAnimation();
}
}*/
canvas.drawArc(rect, startAngle, sweepAngle, false, myPaint);
startAngle = -90;
invalidate();
//取消註釋,可以演示對號效果
/*if(progressFlag==true){
m.finalAnimation();
}*/
}
}
MasterLayout.java
//圓形進度條
public class MasterLayout extends FrameLayout {
public CusImage cusview;
public int pix = 0;
public RectF rect;
private ImageView buttonimage, fillcircle, full_circle_image, arc_image;
private Path tick, download_triangle, download_rectangle;
private Bitmap third_icon_bmp, second_icon_bmp, first_icon_bmp;
private Paint stroke_color, fill_color, icon_color, final_icon_color;
private AnimationSet in, out;
private RotateAnimation arcRotation;
private ScaleAnimation new_scale_in, scale_in, scale_out;
private AlphaAnimation fade_in, fade_out;
public int flg_frmwrk_mode = 0;
boolean first_click = false;
Canvas full_circle_canvas;
public MasterLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
initialise();
setpaint();
setAnimation();
displayMetrics();
iconCreate();
init(true);
}
public MasterLayout(Context context) {
super(context);
setBackgroundColor(Color.CYAN);
initialise();
setpaint();
setAnimation();
displayMetrics();
iconCreate();
init(true);
}
private void initialise() {
cusview = new CusImage(getContext(), this);
buttonimage = new ImageView(getContext());
full_circle_image = new ImageView(getContext());
arc_image = new ImageView(getContext());
fillcircle = new ImageView(getContext());
cusview.setClickable(false);
buttonimage.setClickable(false);
full_circle_image.setClickable(false);
arc_image.setClickable(false);
cusview.setClickable(false);
setClickable(true);
fillcircle.setClickable(false);
}
private void setpaint() {
// Setting up color
stroke_color = new Paint(Paint.ANTI_ALIAS_FLAG);
stroke_color.setAntiAlias(true);
stroke_color.setColor(getResources().getColor(R.color.baseGreen)); // Edit this to change
// the circle color
stroke_color.setStrokeWidth(15);
stroke_color.setStyle(Paint.Style.STROKE);
icon_color = new Paint(Paint.ANTI_ALIAS_FLAG);
icon_color.setColor(getResources().getColor(R.color.baseGreen));
icon_color.setStyle(Paint.Style.FILL_AND_STROKE); // Edit this to change
// the icon color
icon_color.setAntiAlias(true);
final_icon_color = new Paint(Paint.ANTI_ALIAS_FLAG);
final_icon_color.setColor(getResources().getColor(R.color.baseGreen)); // Edit this to change the final
// icon color
final_icon_color.setStrokeWidth(15);
final_icon_color.setStyle(Paint.Style.STROKE);
final_icon_color.setAntiAlias(true);
fill_color = new Paint(Paint.ANTI_ALIAS_FLAG);
fill_color.setColor(getResources().getColor(R.color.baseGreen)); // Edit this to change the
// circle fill color
//fill_color.setStrokeWidth(15);
fill_color.setStyle(Paint.Style.FILL_AND_STROKE);
fill_color.setAntiAlias(true);
}
private void setAnimation() {
// Setting up and defining view animations.
arcRotation = new RotateAnimation(0.0f, 360.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
arcRotation.setDuration(1000);
in = new AnimationSet(true);
out = new AnimationSet(true);
out.setInterpolator(new AccelerateDecelerateInterpolator());
in.setInterpolator(new AccelerateDecelerateInterpolator());
scale_in = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
scale_out = new ScaleAnimation(1.0f, 3.0f, 1.0f, 3.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
new_scale_in = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
new_scale_in.setDuration(200);
fade_in = new AlphaAnimation(0.0f, 1.0f);
fade_out = new AlphaAnimation(1.0f, 0.0f);
scale_in.setDuration(150);
scale_out.setDuration(150);
fade_in.setDuration(150);
fade_out.setDuration(150);
in.addAnimation(scale_in);
in.addAnimation(fade_in);
out.addAnimation(fade_out);
out.addAnimation(scale_out);
arcRotation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation arg0) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animation arg0) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation arg0) {
// TODO Auto-generated method stub
first_click = false;
buttonimage.startAnimation(out);
}
});
out.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
System.out.println("print this");
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
buttonimage.setVisibility(View.GONE);
buttonimage.setImageBitmap(second_icon_bmp);
buttonimage.setVisibility(View.VISIBLE);
buttonimage.startAnimation(in);
arc_image.setVisibility(View.GONE);
full_circle_image.setVisibility(View.VISIBLE);
cusview.setVisibility(View.VISIBLE);
flg_frmwrk_mode = 2;
System.out.println("flg_frmwrk_mode" + flg_frmwrk_mode);
}
});
new_scale_in.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
cusview.setVisibility(View.GONE);
buttonimage.setVisibility(View.VISIBLE);
buttonimage.setImageBitmap(third_icon_bmp);
full_circle_canvas.drawArc(rect, 0, 360, false, stroke_color);
flg_frmwrk_mode = 3;
buttonimage.startAnimation(in);
}
});
}
private void displayMetrics() {
// Responsible for calculating the size of views and canvas based upon
// screen resolution.
DisplayMetrics metrics = getContext().getResources()
.getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;
float scarea = width * height;
pix = (int) Math.sqrt(scarea * 0.07);
}
private void iconCreate() {
// Creating icons using path
// Create your own icons or feel free to use these
/* play = new Path();
play.moveTo(pix * 40 / 100, pix * 36 / 100);
play.lineTo(pix * 40 / 100, pix * 63 / 100);
play.lineTo(pix * 69 / 100, pix * 50 / 100);
play.close();
stop = new Path();
stop.moveTo(pix * 38 / 100, pix * 38 / 100);
stop.lineTo(pix * 62 / 100, pix * 38 / 100);
stop.lineTo(pix * 62 / 100, pix * 62 / 100);
stop.lineTo(pix * 38 / 100, pix * 62 / 100);
stop.close();*/
download_triangle = new Path();
download_triangle.moveTo(pix * 375 / 1000, (pix / 2)
+ (pix * 625 / 10000) - (pix * 3 / 100));
download_triangle.lineTo(pix / 2, (pix * 625 / 1000)
+ (pix * 625 / 10000) - (pix * 3 / 100));
download_triangle.lineTo(pix * 625 / 1000, (pix / 2)
+ (pix * 625 / 10000) - (pix * 3 / 100));
download_triangle.close();
download_rectangle = new Path();
download_rectangle.moveTo(pix * 4375 / 10000, (pix / 2)
+ (pix * 625 / 10000) - (pix * 3 / 100));
download_rectangle.lineTo(pix * 5625 / 10000, (pix / 2)
+ (pix * 625 / 10000) - (pix * 3 / 100));
download_rectangle.lineTo(pix * 5625 / 10000, (pix * 375 / 1000)
+ (pix * 625 / 10000) - (pix * 3 / 100));
download_rectangle.lineTo(pix * 4375 / 10000, (pix * 375 / 1000)
+ (pix * 625 / 10000) - (pix * 3 / 100));
download_rectangle.close();
tick = new Path();
tick.moveTo(pix * 30 / 100, pix * 50 / 100);
tick.lineTo(pix * 45 / 100, pix * 625 / 1000);
tick.lineTo(pix * 65 / 100, pix * 350 / 1000);
}
//第一次初始化,預設顯示圓形,其他呼叫,不顯示圓形
public void init(boolean isFirstInit) {
// Defining and drawing bitmaps and assigning views to the layout
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(10, 10, 10, 10);
fillcircle.setVisibility(View.GONE);
Bitmap.Config conf = Bitmap.Config.ARGB_8888; // see other conf types
Bitmap full_circle_bmp = Bitmap.createBitmap(pix, pix, conf);
Bitmap arc_bmp = Bitmap.createBitmap(pix, pix, conf);
Bitmap fill_circle_bmp = Bitmap.createBitmap(pix, pix, conf);
first_icon_bmp = Bitmap.createBitmap(pix, pix, conf); // Bitmap to draw
// first icon(
// Default -
// Play )
second_icon_bmp = Bitmap.createBitmap(pix, pix, conf); // Bitmap to draw
// second icon(
// Default -
// Stop )
third_icon_bmp = Bitmap.createBitmap(pix, pix, conf); // Bitmap to draw
// third icon(
// Default -
// Tick )
//Canvas first_icon_canvas = new Canvas(first_icon_bmp);
//Canvas second_icon_canvas = new Canvas(second_icon_bmp);
Canvas third_icon_canvas = new Canvas(third_icon_bmp);
//Canvas fill_circle_canvas = new Canvas(fill_circle_bmp);
full_circle_canvas = new Canvas(full_circle_bmp);
//Canvas arc_canvas = new Canvas(arc_bmp);
float startx = (float) (pix * 0.05);
float endx = (float) (pix * 0.95);
System.out.println("full circle " + full_circle_canvas.getWidth()
+ full_circle_canvas.getHeight());
float starty = (float) (pix * 0.05);
float endy = (float) (pix * 0.95);
rect = new RectF(startx, starty, endx, endy);
//first_icon_canvas.drawPath(play, fill_color); // Draw second icon on canvas( Default - Stop ).
// *****Set your second icon here****
//second_icon_canvas.drawPath(stop, icon_color); // Draw second icon on canvas( Default - Stop ).
// *****Set your second icon here****
third_icon_canvas.drawPath(tick, final_icon_color); // Draw second icon on canvas( Default - Stop ).
// *****Set your second icon here****
if(isFirstInit){
full_circle_canvas.drawArc(rect, 0, 360, false, stroke_color);
}
//fill_circle_canvas.drawArc(rect, 0, 360, false, fill_color);
//arc_canvas.drawArc(rect, -80, 340, false, stroke_color);
buttonimage.setImageBitmap(first_icon_bmp);
flg_frmwrk_mode = 1;
fillcircle.setImageBitmap(fill_circle_bmp);
full_circle_image.setImageBitmap(full_circle_bmp);
arc_image.setImageBitmap(arc_bmp);
cusview.setVisibility(View.GONE);
addView(full_circle_image, lp);
addView(arc_image, lp);
addView(fillcircle, lp);
addView(buttonimage, lp);
addView(cusview, lp);
buttonimage.setVisibility(View.GONE);
fillcircle.setVisibility(View.GONE);
}
public void animation() {
// Starting view animation and setting flag values
if (first_click == false) {
if (flg_frmwrk_mode == 1) {
//去掉所有views,重新初始化,進行動畫
removeAllViews();
fill_color.setColor(getResources().getColor(R.color.black));
init(false);
first_click = true;
full_circle_image.setVisibility(View.GONE);
/*arc_image.setVisibility(View.VISIBLE);
arc_image.startAnimation(arcRotation);*/
buttonimage.setVisibility(View.GONE);
buttonimage.setImageBitmap(second_icon_bmp);
buttonimage.setVisibility(View.VISIBLE);
buttonimage.startAnimation(in);
arc_image.setVisibility(View.GONE);
full_circle_image.setVisibility(View.VISIBLE);
cusview.setVisibility(View.VISIBLE);
}
}
}
public void finalAnimation() {
// Responsible for final fill up animation
buttonimage.setVisibility(View.GONE);
fillcircle.setVisibility(View.VISIBLE);
fillcircle.startAnimation(new_scale_in);
}
public void reset() {
// Responsible for resetting the state of view when Stop is clicked
cusview.reset();
cusview.setVisibility(View.GONE);
buttonimage.setImageBitmap(first_icon_bmp);
flg_frmwrk_mode = 1;
}
//點選控制元件,需要先填滿圓形,然後將圓形取消,進行動畫
public void onClick(){
removeAllViews();
init(false);
full_circle_canvas.drawArc(rect, 0, 360, false, fill_color);
}
}
MainActivity.java
mIdTextViewSign.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mIdTextViewSign.setClickable(false);
mMasterLayout01.onClick();
mIdTextViewSign.setTextColor(getResources().getColor(R.color.white));
new Handler().postDelayed(new Runnable() {
public void run() {
//mMasterLayout01.removeViews();
mIdTextViewSign.setVisibility(View.GONE);
mMasterLayout01.animation(); //Need to call this method for animation and progression
if (mMasterLayout01.flg_frmwrk_mode == 1) {
if(mTimer==null){
mTimer = new Timer();
mTimerTask = new TimerTask() {
@Override
public void run() {
progress++;
if (progress == 100) {
progress = 0;
if (mMasterLayout01.cusview.progressFlag) {
mMasterLayout01.cusview.progressFlag = false;
} else {
mMasterLayout01.cusview.progressFlag = true;
}
}
if (mMasterLayout01.cusview.progressFlag) {
mMasterLayout01.cusview.setupprogress(progress);
} else {
mMasterLayout01.cusview.setupprogress2(progress);
}
}
};
//開始一個定時任務
mTimer.schedule(mTimerTask, 0, 10);
}
}
}
}, 500);
}
});
activity_main.xml
//省略...
<FrameLayout
android:id="@+id/id_frameLayoutSign"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="45dp">
<boerpower.com.electricmanager.CustomViews.MasterLayout
android:id="@+id/MasterLayout01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
>
</boerpower.com.electricmanager.CustomViews.MasterLayout>
<TextView
android:id="@+id/id_textViewSign"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#2ebea0"
android:textSize="18sp"
android:layout_margin="10dp"
android:textStyle="bold"
android:text="簽到"
android:layout_gravity="center"
/>
</FrameLayout>