Android自定义控件之三点循环缩放效果
程序员文章站
2022-06-19 19:48:18
本文实例为大家分享了android自定义控件之三点循环缩放的具体代码,供大家参考,具体内容如下
效果图如上,就是三点循环的变大、变小
package com...
本文实例为大家分享了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 多点循环缩放
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。