亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

Android自定義控件之三點循環縮放效果

2019-10-21 21:38:05
字體:
來源:轉載
供稿:網友

本文實例為大家分享了Android自定義控件之三點循環縮放的具體代碼,供大家參考,具體內容如下

Android,自定義控件,三點循環縮放

效果圖如上,就是三點循環的變大、變小

package com.example.dotdemo;import java.util.ArrayList;import java.util.List;import android.animation.Animator;import android.animation.AnimatorListenerAdapter;import android.animation.ObjectAnimator;import android.animation.ValueAnimator;import android.annotation.SuppressLint;import android.annotation.TargetApi;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.drawable.Drawable;import android.os.Build;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.animation.AccelerateDecelerateInterpolator;@TargetApi(Build.VERSION_CODES.HONEYCOMB)@SuppressLint("NewApi")public class DilatingDotsProgressBar extends View { public static final String TAG = DilatingDotsProgressBar.class.getSimpleName(); public static final double START_DELAY_FACTOR = 0.35; private static final float DEFAULT_GROWTH_MULTIPLIER = 1.75f; private static final int MIN_SHOW_TIME = 500; // ms private static final int MIN_DELAY = 500; // ms private int mDotColor; private int mAnimationDuration; private int mWidthBetweenDotCenters; private int mNumberDots; private float mDotRadius; private float mDotScaleMultiplier; private float mDotMaxRadius; private float mHorizontalSpacing; private long mStartTime = -1; private boolean mShouldAnimate; private boolean mDismissed = false; private ArrayList<DilatingDotDrawable> mDrawables = new ArrayList<DilatingDotDrawable>(); private final List<Animator> mAnimations = new ArrayList<Animator>(); /** delayed runnable to stop the progress */ private final Runnable mDelayedHide = new Runnable() { @Override public void run() {  mStartTime = -1;  setVisibility(View.GONE);  stopAnimations(); } }; /** delayed runnable to start the progress */ private final Runnable mDelayedShow = new Runnable() { @Override public void run() {  if (!mDismissed) {  mStartTime = System.currentTimeMillis();  setVisibility(View.VISIBLE);  startAnimations();  } } }; public DilatingDotsProgressBar(Context context) { this(context, null); } public DilatingDotsProgressBar(Context context, AttributeSet attrs) { this(context, attrs, 0); } public DilatingDotsProgressBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(attrs); } private void init(AttributeSet attrs) { TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.DilatingDotsProgressBar); mNumberDots = a.getInt(R.styleable.DilatingDotsProgressBar_dd_numDots, 3); mDotRadius = a.getDimension(R.styleable.DilatingDotsProgressBar_android_radius, 8); mDotColor = a.getColor(R.styleable.DilatingDotsProgressBar_android_color, 0xff9c27b0); mDotScaleMultiplier = a.getFloat(R.styleable.DilatingDotsProgressBar_dd_scaleMultiplier, DEFAULT_GROWTH_MULTIPLIER); mAnimationDuration = a.getInt(R.styleable.DilatingDotsProgressBar_dd_animationDuration, 300); mHorizontalSpacing = a.getDimension(R.styleable.DilatingDotsProgressBar_dd_horizontalSpacing, 12); boolean isShow = a.getBoolean(R.styleable.DilatingDotsProgressBar_dd_show_now, false); a.recycle(); mShouldAnimate = false; calculateMaxRadius(); calculateWidthBetweenDotCenters(); initDots(); updateDots(); if (isShow) {  showNow(); } } @Override protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) { super.onSizeChanged(w, h, oldw, oldh); if (computeMaxHeight() != h || w != computeMaxWidth()) {  updateDots(); } } @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); removeCallbacks(); } private void removeCallbacks() { removeCallbacks(mDelayedHide); removeCallbacks(mDelayedShow); } public void reset() { hideNow(); } /** * Hide the progress view if it is visible. The progress view will not be * hidden until it has been shown for at least a minimum show time. If the * progress view was not yet visible, cancels showing the progress view. */ public void hide() { hide(MIN_SHOW_TIME); } public void hide(int delay) { mDismissed = true; removeCallbacks(mDelayedShow); long diff = System.currentTimeMillis() - mStartTime; if ((diff >= delay) || (mStartTime == -1)) {  mDelayedHide.run(); } else {  if ((delay - diff) <= 0) {  mDelayedHide.run();  } else {  postDelayed(mDelayedHide, delay - diff);  } } } /** * Show the progress view after waiting for a minimum delay. If * during that time, hide() is called, the view is never made visible. */ @SuppressWarnings ("unused") public void show() { show(MIN_DELAY); } @SuppressWarnings ("unused") public void showNow() { show(0); } @SuppressWarnings ("unused") public void hideNow() { hide(0); } public void show(int delay) { mStartTime = -1; mDismissed = false; removeCallbacks(mDelayedHide); if (delay == 0) {  mDelayedShow.run(); } else {  postDelayed(mDelayedShow, delay); } } @Override protected void onDraw(Canvas canvas) { if (shouldAnimate()) {  for (DilatingDotDrawable dot : mDrawables) {  dot.draw(canvas);  } } } @Override protected boolean verifyDrawable(final Drawable who) { if (shouldAnimate()) {  return mDrawables.contains(who); } return super.verifyDrawable(who); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension((int) computeMaxWidth(), (int) computeMaxHeight()); } private float computeMaxHeight() { return mDotMaxRadius * 2; } private float computeMaxWidth() { return computeWidth() + ((mDotMaxRadius - mDotRadius) * 2); } private float computeWidth() { return (((mDotRadius * 2) + mHorizontalSpacing) * mDrawables.size()) - mHorizontalSpacing; } private void calculateMaxRadius() { mDotMaxRadius = mDotRadius * mDotScaleMultiplier; } private void calculateWidthBetweenDotCenters() { mWidthBetweenDotCenters = (int) (mDotRadius * 2) + (int) mHorizontalSpacing; } @SuppressLint("NewApi") private void initDots() { mDrawables.clear(); mAnimations.clear(); Log.i("lcf", "mAnimationDuration = "+mAnimationDuration ); for (int i = 1; i <= mNumberDots; i++) {  final DilatingDotDrawable dot = new DilatingDotDrawable(mDotColor, mDotRadius, mDotMaxRadius);  dot.setCallback(this);  mDrawables.add(dot);  ValueAnimator growAnimator = ObjectAnimator.ofFloat(dot, "radius", mDotRadius, mDotMaxRadius, mDotRadius);  growAnimator.setDuration(mAnimationDuration);  growAnimator.setInterpolator(new AccelerateDecelerateInterpolator());  if (i == mNumberDots) {  growAnimator.addListener(new AnimatorListenerAdapter() {   @TargetApi(Build.VERSION_CODES.HONEYCOMB)   @Override   public void onAnimationEnd(Animator animation) {   if (shouldAnimate()) {    startAnimations();//注意這個地方,是從新開始啟動動畫   }   }  });  }  growAnimator.setStartDelay((i - 1) * (int) (START_DELAY_FACTOR * mAnimationDuration));  mAnimations.add(growAnimator); } } @SuppressLint("NewApi") private void updateDots() { if (mDotRadius <= 0) {  mDotRadius = getHeight() / 2 / mDotScaleMultiplier; } int left = (int) (mDotMaxRadius - mDotRadius); int right = (int) (left + mDotRadius * 2) + 2; int top = 0; int bottom = (int) (mDotMaxRadius * 2) + 2; for (int i = 0; i < mDrawables.size(); i++) {  final DilatingDotDrawable dot = mDrawables.get(i);  dot.setRadius(mDotRadius);  dot.setBounds(left, top, right, bottom);  ValueAnimator growAnimator = (ValueAnimator) mAnimations.get(i);  growAnimator.setFloatValues(mDotRadius, mDotRadius * mDotScaleMultiplier, mDotRadius);  left += mWidthBetweenDotCenters;  right += mWidthBetweenDotCenters; } } protected void startAnimations() { mShouldAnimate = true; for (Animator anim : mAnimations) {  anim.start(); } } protected void stopAnimations() { mShouldAnimate = false; removeCallbacks(); for (Animator anim : mAnimations) {  anim.cancel(); } } protected boolean shouldAnimate() { return mShouldAnimate; } // ------------------------------- // ------ Getters & Setters ------ // ------------------------------- public void setDotRadius(float radius) { reset(); mDotRadius = radius; calculateMaxRadius(); calculateWidthBetweenDotCenters(); setupDots(); } public void setDotSpacing(float horizontalSpacing) { reset(); mHorizontalSpacing = horizontalSpacing; calculateWidthBetweenDotCenters(); setupDots(); } public void setGrowthSpeed(int growthSpeed) { reset(); mAnimationDuration = growthSpeed; setupDots(); } public void setNumberOfDots(int numDots) { reset(); mNumberDots = numDots; setupDots(); } public void setDotScaleMultpiplier(float multplier) { reset(); mDotScaleMultiplier = multplier; calculateMaxRadius(); setupDots(); } public void setDotColor(int color) { mDotColor = color; for (DilatingDotDrawable dot : mDrawables) {  dot.setColor(mDotColor); } } private void setupDots() { initDots(); updateDots(); showNow(); } public int getDotGrowthSpeed() { return mAnimationDuration; } public float getDotRadius() { return mDotRadius; } public float getHorizontalSpacing() { return mHorizontalSpacing; } public int getNumberOfDots() { return mNumberDots; } public float getDotScaleMultiplier() { return mDotScaleMultiplier; }}

 

package com.example.dotdemo;import android.annotation.SuppressLint;import android.graphics.Canvas;import android.graphics.ColorFilter;import android.graphics.Paint;import android.graphics.PixelFormat;import android.graphics.Rect;import android.graphics.drawable.Drawable;@SuppressLint("Override")public class extends Drawable { private static final String TAG = DilatingDotDrawable.class.getSimpleName(); private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private float radius; private float maxRadius; final Rect mDirtyBounds = new Rect(0, 0, 0, 0); public DilatingDotDrawable(final int color, final float radius, final float maxRadius) { mPaint.setColor(color); mPaint.setStyle(Paint.Style.FILL); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeJoin(Paint.Join.ROUND); this.radius = radius; setMaxRadius(maxRadius); } @Override public void draw(Canvas canvas) { final Rect bounds = getBounds(); canvas.drawCircle(bounds.centerX(), bounds.centerY(), radius - 1, mPaint); } @Override public void setAlpha(int alpha) { if (alpha != mPaint.getAlpha()) {  mPaint.setAlpha(alpha);  invalidateSelf(); } } @Override public void setColorFilter(ColorFilter colorFilter) { mPaint.setColorFilter(colorFilter); invalidateSelf(); } @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; } public void setColor(int color) { mPaint.setColor(color); invalidateSelf(); } public void setRadius(float radius) { this.radius = radius; invalidateSelf(); } public float getRadius() { return radius; } @Override public int getIntrinsicWidth() { return (int) (maxRadius * 2) + 2; } @Override public int getIntrinsicHeight() { return (int) (maxRadius * 2) + 2; } public void setMaxRadius(final float maxRadius) { this.maxRadius = maxRadius; mDirtyBounds.bottom = (int) (maxRadius * 2) + 2; mDirtyBounds.right = (int) (maxRadius * 2) + 2; } public Rect getDirtyBounds() { return mDirtyBounds; } @Override protected void onBoundsChange(final Rect bounds) { super.onBoundsChange(bounds); mDirtyBounds.offsetTo(bounds.left, bounds.top); }}

源碼下載:Android 多點循環縮放

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美美女18p| 精品久久久久久电影| 国产精品18久久久久久首页狼| 国内精品视频久久| 亚洲成人av片在线观看| 国产精品久久久久一区二区| 91精品国产电影| 欧美乱妇高清无乱码| 亚洲欧美制服综合另类| 91亚洲国产成人精品性色| 最新国产成人av网站网址麻豆| 欧美激情久久久| 久久综合亚洲社区| 国产在线视频2019最新视频| 亚洲电影免费观看| 国产精品久久久久久久久借妻| 中文字幕精品在线视频| 欧洲美女免费图片一区| 欧美色videos| 日韩av片永久免费网站| 久久久久国产精品www| 91精品国产自产在线观看永久| 日本最新高清不卡中文字幕| 久久成人精品电影| 欧美成人h版在线观看| 亚洲一区二区三区香蕉| 亚洲欧洲日韩国产| 国内精品久久久久久中文字幕| 亚洲国产精品小视频| 亚洲视频在线看| 国产91在线高潮白浆在线观看| 精品一区二区电影| 狠狠色噜噜狠狠狠狠97| 91精品久久久久久久久久久久久| 欧美日韩福利电影| 久久影院在线观看| 国产精品扒开腿做爽爽爽的视频| 亚洲的天堂在线中文字幕| 中文字幕亚洲无线码在线一区| 亚洲理论电影网| 91久久精品美女高潮| 欧洲成人午夜免费大片| 国产欧美在线观看| 亚洲日本欧美日韩高观看| 国产精品自拍视频| 热久久免费国产视频| 久热精品视频在线| 91中文字幕一区| 日韩成人中文电影| 亚洲成色777777在线观看影院| 日韩欧美精品网址| 国产成人综合精品| 亚洲欧美日韩精品久久| 色综合久久精品亚洲国产| 亚洲香蕉av在线一区二区三区| 青青在线视频一区二区三区| 成人国产精品免费视频| www亚洲精品| 国产主播喷水一区二区| 成人有码在线视频| 日韩一区在线视频| 日韩av在线免费播放| 国产一区二区日韩精品欧美精品| 久久久久久久999| 91人人爽人人爽人人精88v| 日韩精品在线观看网站| 国产日韩欧美中文在线播放| 91精品国产综合久久久久久蜜臀| 国产精品视频免费在线| 亚洲福利在线视频| 欧美性色视频在线| 全色精品综合影院| 色偷偷88888欧美精品久久久| 海角国产乱辈乱精品视频| 亚洲女成人图区| 97久久久免费福利网址| 亚洲女同精品视频| 色婷婷综合成人| 欧美电影院免费观看| 久久91亚洲精品中文字幕| 色婷婷亚洲mv天堂mv在影片| 69av在线视频| 成人精品在线视频| 一区二区三区美女xx视频| 丝袜亚洲另类欧美重口| 国产999视频| 国产亚洲精品美女久久久| 国产成人avxxxxx在线看| 亚洲欧美日韩在线一区| 欧美丰满片xxx777| 亚洲午夜久久久久久久| 亚洲欧美国产日韩中文字幕| 亚洲成人av中文字幕| 久久偷看各类女兵18女厕嘘嘘| 亚洲韩国日本中文字幕| 国产69精品久久久久99| 国产精品嫩草影院久久久| 亚洲欧洲视频在线| 亚洲午夜精品久久久久久久久久久久| 精品女同一区二区三区在线播放| 欧美成人亚洲成人日韩成人| 亚洲国产精品yw在线观看| 国产精品成人一区| 欧美大胆在线视频| 亚洲肉体裸体xxxx137| 成人av.网址在线网站| 久久综合伊人77777蜜臀| 欧美亚洲国产日韩2020| 中文字幕在线观看日韩| 国产午夜精品麻豆| 在线观看日韩av| 亚洲精品网站在线播放gif| 亚洲精品电影网站| 日韩电影在线观看永久视频免费网站| 日本亚洲欧美成人| 亚洲视频欧美视频| 久久久久久中文字幕| 人妖精品videosex性欧美| 自拍偷拍亚洲欧美| 久久久亚洲福利精品午夜| 久久国产精品免费视频| 日本精品视频在线观看| 精品久久久一区| 狠狠色噜噜狠狠狠狠97| 国产精品偷伦免费视频观看的| 亚洲美女自拍视频| 日本精品一区二区三区在线播放视频| 欧美激情中文网| 亚洲欧洲日韩国产| 亚洲国产精品女人久久久| 午夜精品久久久久久久久久久久久| 日韩不卡在线观看| 午夜免费在线观看精品视频| 亚洲精品自产拍| 成人免费看黄网站| 国产精品美乳一区二区免费| 色中色综合影院手机版在线观看| 91久久久久久久久久久久久| 久久精品亚洲94久久精品| 欧美亚洲成人网| 日韩久久午夜影院| 国产中文字幕亚洲| 久久夜精品香蕉| 亚洲在线免费观看| 亚洲成色777777女色窝| 欧美性猛交xxxx免费看漫画| 国产成人极品视频| 久久69精品久久久久久国产越南| 免费不卡欧美自拍视频| 精品久久久久久久久国产字幕| 久久亚洲国产精品成人av秋霞| 国产日韩中文字幕在线| 日韩免费观看网站| 精品视频一区在线视频| 欧美激情视频一区二区| 亚洲国产精品久久久久| 亚洲欧美精品伊人久久| 精品性高朝久久久久久久| 欧美性xxxxxxxxx| 91精品久久久久久久久| 一区二区欧美日韩视频| 国产婷婷97碰碰久久人人蜜臀| 国产精品视频一| 国产精品视频xxx|