最近,看了好多的APP的等待对话框,发现自己的太lower,于是就研究了一番,最后经过苦心努力,实现一个。
自定义一个LoadingIndicatorVIEw(extends VIEw )类 编写values/attrs.xml,在其中编写styleable和item等标签元素 在布局文件中LoadingIndicatorVIEw使用自定义的属性(注意namespace) 在LoadingIndicatorVIEw的构造方法中通过TypedArray获取描述就提供这些,一下是代码的展示,非常的详细。
1、自定义属性的声明文件
<declare-styleable name="AVLoadingIndicatorVIEw"> <attr name="indicator"> <flag name="BallSpinFadeLoader" value="22"/> </attr> <attr name="indicator_color" format="color"/> </declare-styleable> <pre name="code" >
LoadingIndicatorVIEw.java
import androID.annotation.TargetAPI; import androID.content.Context; import androID.content.res.TypedArray; import androID.graphics.Canvas; import androID.graphics.color; import androID.graphics.Paint; import androID.os.Build; import androID.support.annotation.IntDef; import androID.util.AttributeSet; import androID.vIEw.VIEw; import com.chni.lIDong.androIDtestdemo.R; /** * Created by lIDongon 2016/1/31 * .BallSpinFadeLoader,* */ public class LoadingIndicatorVIEw extends VIEw { //indicators 指示器 public static final int BallSpinFadeLoader=22; @IntDef(flag = true,value = { BallSpinFadeLoader,}) public @interface Indicator{} //Sizes (with defaults in DP) public static final int DEFAulT_SIZE=45; //attrs int mIndicatorID; int mIndicatorcolor; Paint mPaint; BaseIndicatorController mIndicatorController; private boolean mHasAnimation; public LoadingIndicatorVIEw(Context context) { super(context); init(null,0); } public LoadingIndicatorVIEw(Context context,AttributeSet attrs) { super(context,attrs); init(attrs,AttributeSet attrs,int defStyleAttr) { super(context,attrs,defStyleAttr); init(attrs,defStyleAttr); } @TargetAPI(Build.VERSION_CODES.LolliPOP) public LoadingIndicatorVIEw(Context context,int defStyleAttr,int defStyleRes) { super(context,defStyleAttr,defStyleRes); init(attrs,defStyleAttr); } private voID init(AttributeSet attrs,int defStyle) { /** *获取TypedArray(属性的集合) */ TypedArray a = getContext().obtainStyledAttributes(attrs,R.styleable.AVLoadingIndicatorVIEw); mIndicatorID=a.getInt(R.styleable.AVLoadingIndicatorVIEw_indicator,BallSpinFadeLoader);//获取编号属性 mIndicatorcolor=a.getcolor(R.styleable.AVLoadingIndicatorVIEw_indicator_color,color.WHITE);//获取颜色属性 a.recycle();//回收属性的集合 mPaint=new Paint(); mPaint.setcolor(mIndicatorcolor);//设置画笔的颜色 mPaint.setStyle(Paint.Style.FILL);//设置画笔的样式为填充 mPaint.setAntiAlias(true);//去锯齿 applyIndicator();// } private voID applyIndicator(){ switch (mIndicatorID){ case BallSpinFadeLoader: mIndicatorController=new BallSpinFadeLoaderIndicator(); break; } mIndicatorController.setTarget(this);//将控件设置到当前VIEw } @OverrIDe protected voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) { int wIDth = measureDimension(dp2px(DEFAulT_SIZE),wIDthMeasureSpec);//获取VIEw的宽度 int height = measureDimension(dp2px(DEFAulT_SIZE),heightmeasureSpec);//获取VIEw的高度 setMeasuredDimension(wIDth,height);// } /** *测量的 维度 * @param defaultSize 默认大小 * @param measureSpec {@see wIDthMeasureSpec,heightmeasureSpec} * @return 返回测量的结果 */ private int measureDimension(int defaultSize,int measureSpec){ int result = defaultSize; int specMode = MeasureSpec.getMode(measureSpec);//测量规范 int specsize = MeasureSpec.getSize(measureSpec);//测量大小 if (specMode == MeasureSpec.EXACTLY) {//父控件已经为子控件设置确定的大小,子控件会考虑父控件给他的大小,自己需要多大设置多大 result = specsize; } else if (specMode == MeasureSpec.AT_MOST) {//子控件可以设置自己希望的指定大小 result = Math.min(defaultSize,specsize);//取最小值 } else { result = defaultSize; } return result; } @OverrIDe protected voID onDraw(Canvas canvas) { super.onDraw(canvas); drawIndicator(canvas); } @OverrIDe protected voID onLayout(boolean changed,int left,int top,int right,int bottom) { super.onLayout(changed,left,top,right,bottom); if (!mHasAnimation){ mHasAnimation=true; applyAnimation(); } } voID drawIndicator(Canvas canvas){ mIndicatorController.draw(canvas,mPaint); } voID applyAnimation(){ mIndicatorController.createAnimation(); } private int dp2px(int dpValue) { return (int) getContext().getResources().getdisplayMetrics().density * dpValue; }
BaseIndicatorController.java
package com.chni.lIDong.androIDtestdemo.loading; import androID.graphics.Canvas; import androID.graphics.Paint; import androID.vIEw.VIEw; /** * Created by lIDongon 2016/1/31 */ public abstract class BaseIndicatorController { private VIEw mTarget; public voID setTarget(VIEw target){ this.mTarget=target; } public VIEw getTarget(){ return mTarget; } /** * 得到VIEw的宽度 * @return */ public int getWIDth(){ return mTarget.getWIDth(); } /** * 得到vIEw的高度 * @return */ public int getHeight(){ return mTarget.getHeight(); } /** * 刷新vIEw */ public voID postInvalIDate(){ mTarget.postInvalIDate(); } /** * draw indicator what ever * you want to draw * 绘制indicate * @param canvas * @param paint */ public abstract voID draw(Canvas canvas,Paint paint); /** * create animation or animations *,and add to your indicator. * 创建动画或者动画集合,添加到indcator */ public abstract voID createAnimation(); }
BallSpinFadeLoaderIndicator.java
package com.chni.lIDong.androIDtestdemo.loading; import androID.graphics.Canvas; import androID.graphics.Paint; import com.nineoldandroIDs.animation.ValueAnimator; /** * Created by lIDongon 2016/1/31 */ public class BallSpinFadeLoaderIndicator extends BaseIndicatorController { public static final float SCALE=1.0f; public static final int Alpha=255; /** * 圆点的比例 */ float[] scalefloats=new float[]{SCALE,SCALE,SCALE}; /** * 圆点的透明度集合 */ int[] Alphas=new int[]{Alpha,Alpha,Alpha}; @OverrIDe public voID draw(Canvas canvas,Paint paint) { float radius=getWIDth()/10; for (int i = 0; i < 8; i++) { canvas.save(); Point point=circleAt(getWIDth(),getHeight(),getWIDth()/2-radius,i*(Math.PI/4)); canvas.translate(point.x,point.y); canvas.scale(scalefloats[i],scalefloats[i]); paint.setAlpha(Alphas[i]); canvas.drawCircle(0,radius,paint); canvas.restore(); } } /** * 圆O的圆心为(a,b),半径为R,点A与到X轴的为角α. *则点A的坐标为(a+R*cosα,b+R*sinα) * @param wIDth * @param height * @param radius * @param angle * @return */ Point circleAt(int wIDth,int height,float radius,double angle){ float x= (float) (wIDth/2+radius*(Math.cos(angle))); float y= (float) (height/2+radius*(Math.sin(angle))); return new Point(x,y); } @OverrIDe public voID createAnimation() { int[] delays= {0,120,240,360,480,600,720,780,840}; for (int i = 0; i < 8; i++) { final int index=i; ValueAnimator scaleAnim=ValueAnimator.offloat(1,0.4f,1);//创建ValueAnimator对象 scaleAnim.setDuration(1000);//设置动画的持续时间 scaleAnim.setRepeatCount(-1);//设置动画是否重复 scaleAnim.setStartDelay(delays[i]);//延迟启动动画 scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {//ValueAnimator只负责第一次的内容,因此必须通过监听来实现对象的相关属性的更新 @OverrIDe public voID onAnimationUpdate(ValueAnimator animation) { scalefloats[index] = (float) animation.getAnimatedValue();//获取当前帧的值 postInvalIDate(); } }); scaleAnim.start();//启动属性动画 ValueAnimator AlphaAnim=ValueAnimator.ofInt(255,77,255);//透明度动画 AlphaAnim.setDuration(1000);// AlphaAnim.setRepeatCount(-1); AlphaAnim.setStartDelay(delays[i]); AlphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @OverrIDe public voID onAnimationUpdate(ValueAnimator animation) { Alphas[index] = (int) animation.getAnimatedValue(); postInvalIDate(); } }); AlphaAnim.start(); } } final class Point{ public float x; public float y; public Point(float x,float y){ this.x=x; this.y=y; } } }
UIHelp.java
package com.chni.lIDong.androIDtestdemo.utils; import androID.app.Activity; import androID.app.Dialog; import androID.vIEw.LayoutInflater; import androID.vIEw.VIEw; import androID.Widget.linearLayout; import androID.Widget.TextVIEw; import com.chni.lIDong.androIDtestdemo.R; /** * 对话框的实现 * @author 李东 * @Date 2014-11-23 */ public class UIHelper { /** 加载数据对话框 */ private static Dialog mloadingDialog; /** * 显示加载对话框 * @param context 上下文 * @param msg 对话框显示内容 * @param cancelable 对话框是否可以取消 */ public static voID showDialogForLoading(Activity context,String msg,boolean cancelable) { VIEw vIEw = LayoutInflater.from(context).inflate(R.layout.layout_loading_dialog,null); TextVIEw loadingText = (TextVIEw)vIEw.findVIEwByID(R.ID.ID_tv_loading_dialog_text); loadingText.setText(msg); mloadingDialog = new Dialog(context,R.style.loading_dialog_style); mloadingDialog.setCancelable(cancelable); mloadingDialog.setContentVIEw(vIEw,new linearLayout.LayoutParams(linearLayout.LayoutParams.MATCH_PARENT,linearLayout.LayoutParams.MATCH_PARENT)); mloadingDialog.show(); } /** * 关闭加载对话框 */ public static voID hIDeDialogForLoading() { if(mloadingDialog != null && mloadingDialog.isShowing()) { mloadingDialog.cancel(); } } }
对话框的布局:
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" xmlns:app="http://schemas.androID.com/apk/res-auto" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:background="@drawable/bg_loading_dialog_shape" androID:gravity="center" androID:minHeight="60dp" androID:minWIDth="180dp" androID:orIEntation="vertical" androID:padding="@dimen/padding_10" > <linearLayout androID:layout_wIDth="wrap_content" androID:layout_weight="1" androID:gravity="center" androID:layout_height="wrap_content"> <com.chni.lIDong.androIDtestdemo.loading.AVLoadingIndicatorVIEw androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" app:indicator="BallSpinFadeLoader" app:indicator_color="@color/green" /> </linearLayout> <TextVIEw androID:ID="@+ID/ID_tv_loading_dialog_text" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_margintop="@dimen/padding_5" androID:text="正在登录…" androID:textcolor="@color/content" androID:textSize="14sp" /></linearLayout>
对话框的样式:
<!-- 自定义Loading Dialog --><style name="loading_dialog_style" parent="@androID:style/theme.Dialog"> <item name="androID:windowFrame">@null</item> <item name="androID:windowNoTitle">true</item> <item name="androID:windowBackground">@color/transparent</item> <item name="androID:windowIsfloating">true</item> <item name="androID:windowContentOverlay">@null</item></style>
MainActivity.java
public class Main7Activity extends AppCompatActivity { @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main7); Toolbar toolbar = (Toolbar) findVIEwByID(R.ID.toolbar); setSupportActionbar(toolbar); floatingActionbutton fab = (floatingActionbutton) findVIEwByID(R.ID.fab); fab.setonClickListener(new VIEw.OnClickListener() { @OverrIDe public voID onClick(VIEw vIEw) { Snackbar.make(vIEw,"Replace with your own action",Snackbar.LENGTH_LONG) .setAction("Action",null).show(); } }); UIHelper.showDialogForLoading(this,"正在加载...",true); Handler handler = new Handler(); handler.postDelayed(new Runnable() { @OverrIDe public voID run() { UIHelper.hIDeDialogForLoading(); } },10000); } }
效果图;
以上就是本文的全部内容,希望对大家的学习有所帮助。
总结以上是内存溢出为你收集整理的Android自定义等待对话框全部内容,希望文章能够帮你解决Android自定义等待对话框所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)