最近,看了好多的APP的等待對話框,發(fā)現(xiàn)自己的太lower,于是就研究了一番,最后經(jīng)過苦心努力,實現(xiàn)一個。
描述就提供這些,一下是代碼的展示,非常的詳細。
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" class="html">
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, 0);   }    public LoadingIndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {     super(context, attrs, defStyleAttr);     init(attrs, defStyleAttr);   }     @TargetApi(Build.VERSION_CODES.LOLLIPOP)   public LoadingIndicatorView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {     super(context, attrs, 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);//測量規(guī)范     int specSize = MeasureSpec.getSize(measureSpec);//測量大小     if (specMode == MeasureSpec.EXACTLY) {//父控件已經(jīng)為子控件設置確定的大小,子控件會考慮父控件給他的大小,自己需要多大設置多大       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.    * 創(chuàng)建動畫或者動畫集合,添加到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,       SCALE,       SCALE,       SCALE,       SCALE,       SCALE};   /**    * 圓點的透明度集合    */   int[] alphas=new int[]{ALPHA,       ALPHA,       ALPHA,       ALPHA,       ALPHA,       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,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);//創(chuàng)建ValueAnimator對象       scaleAnim.setDuration(1000);//設置動畫的持續(xù)時間       scaleAnim.setRepeatCount(-1);//設置動畫是否重復       scaleAnim.setStartDelay(delays[i]);//延遲啟動動畫       scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {//ValueAnimator只負責第一次的內容,因此必須通過監(jiān)聽來實現(xiàn)對象的相關屬性的更新         @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;  /**  * 對話框的實現(xiàn)  * @author 李東  * @Date 2014-11-23  */ public class UIHelper {      /** 加載數(shù)據(jù)對話框 */   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);   }  } 效果圖;

以上就是本文的全部內容,希望對大家的學習有所幫助。
新聞熱點
疑難解答
圖片精選