欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android自定义控件之三点循环缩放效果

程序员文章站 2023-12-04 20:47:34
本文实例为大家分享了android自定义控件之三点循环缩放的具体代码,供大家参考,具体内容如下 效果图如上,就是三点循环的变大、变小 package com...

本文实例为大家分享了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 多点循环缩放

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。