当前位置: 移动技术网 > IT编程>移动开发>Android > Android自定义等待对话框

Android自定义等待对话框

2019年07月24日  | 移动技术网IT编程  | 我要评论

名医俏佳人,wupdmgr.exe,菲律宾暴力禁毒运动

最近,看了好多的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" 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);//测量规范 
    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, 
      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);//创建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); 
  } 
 
} 

效果图;

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网