仿WP8樣式的Android ProgressBar

一個WP8樣式的進度對話框。對應Android轉圈圈的ProgressBar。使用方法和普通的dialog一樣


public class Win8ProgressDialog extends Dialog {
    private WPLoading loading;

    public Win8ProgressDialog(Context context) {
        super(context);
    }

    public Win8ProgressDialog(Context context, int theme) {
        super(context, theme);
    }

    public void setLoading(WPLoading loading) {
        this.loading = loading;
    }

    @Override
    public void cancel() {
        loading.cancel();
        super.cancel();
    }

    public Win8ProgressDialog(Context context, boolean cancelable,
            OnCancelListener cancelListener) {
        super(context, cancelable, cancelListener);
    }

    public static class Builder {
        private Context mContext;
        private boolean canceledOnTouchOutside = true;
        private boolean cancelable = true;

        public Builder(Context context) {
            mContext = context;
        }

        public Builder setCanceledOnTouchOutside(boolean flag) {
            canceledOnTouchOutside = flag;
            return this;
        }

        public Builder setCancelable(boolean flag) {
            cancelable = flag;
            return this;
        }

        public Win8ProgressDialog create() {
            final Win8ProgressDialog dialog = new Win8ProgressDialog(mContext,
                    R.style.WPDialog);
            WPLoading loading = new WPLoading(mContext);
            dialog.setLoading(loading);
            dialog.setCancelable(cancelable);
            dialog.setCanceledOnTouchOutside(canceledOnTouchOutside);
            dialog.setCanceledOnTouchOutside(false);
            dialog.addContentView(loading, new LayoutParams(
                    LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
            loading.startAnimate();
            return dialog;
        }
    }

}


WPLoading是Win8ProgressDialog顯示的view,其實是一個包含了運動五個小藍點的RelativeLayout,小藍點的動畫使用了一個先減速後加速的插值器DecelerateAccelerateStopInterpolator


public class WPLoading extends RelativeLayout {

	private int size = 10;
	private int delay = 300;
	private int duration = 3200;
	private String color = "#0000ff";

	private AnimatorSet animatorSet = new AnimatorSet();

	public WPLoading(Context context) {
		super(context);
		LayoutParams params0 = new LayoutParams(
				DisplayUtil.getScreenWidth(context), size);
		View view = new View(context);
		view.setLayoutParams(params0);
		addView(view);
	}

	public void startAnimate() {
		LayoutParams params = new LayoutParams(size, size);
		animatorSet = new AnimatorSet();
		ArrayList<Animator> animators = new ArrayList<Animator>();
		for (int i = 0; i < 5; i++) {
			View view = new View(getContext());
			view.setBackgroundColor(Color.parseColor(color));
			addView(view);
			view.setLayoutParams(params);
			view.setX(-size);

			ObjectAnimator headAnimator = ObjectAnimator.ofFloat(view, "x",
					view.getX(), DisplayUtil.getScreenWidth(getContext()));
			headAnimator.setDuration(duration);
			headAnimator
					.setInterpolator(new DecelerateAccelerateStopInterpolator());
			headAnimator.setStartDelay(delay * i);
			headAnimator.setRepeatCount(-1);
			animators.add(headAnimator);
		}
		animatorSet.playTogether(animators);
		animatorSet.start();
	}

	public WPLoading(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public WPLoading(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public void cancel() {
		animatorSet.end();
	}

	// 先減速再加速的插值器,在加速完成後會再停止一會兒,循環地進行這個動畫,就和WP8的Loading樣式一樣了
	class DecelerateAccelerateStopInterpolator implements
			android.view.animation.Interpolator {
		private float mFactor = 1.0f;
		private float tailFactor = 0.6f;

		public DecelerateAccelerateStopInterpolator() {
		}

		public DecelerateAccelerateStopInterpolator(float factor) {
			mFactor = factor;
		}

		public float getInterpolation(float x) {
			float result;
			if (x > tailFactor) {
				result = 1;
			} else if (x > tailFactor / 2) {
				result = (float) Math.pow(
						(x - tailFactor / 2) * 2 / tailFactor, 2 * mFactor) / 2 + 0.5f;
			} else {
				result = (float) (1.0f - Math.pow((tailFactor - 2 * x)
						/ tailFactor, 2 * mFactor)) / 2;
			}
			return result;
		}
	}
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章