Android自定义加载中Dialog

开发中经常需要请求网络获取数据,我们在请求网络到得到数据时当中需要等待一些时间,为了增加用户体验,我们一般会用一个Dialog来提示用户我们在加载网络数据。今天我们来实现如下效果的加载中Dialog。

从图中我们可以看到要这个Dialog是图片还有文字组成的,(不过我这里使用代码实现的,没有用图片),以下是这个加载图形的代码:

public class LVCircularRing extends View {

private float mWidth = 0f;
private float mPadding = 0f;
private float startAngle = 0f;
private Paint mPaint;

public LVCircularRing(Context context) {
    this(context, null);
}

public LVCircularRing(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public LVCircularRing(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    initPaint();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    if (getMeasuredWidth() > getHeight())
        mWidth = getMeasuredHeight();
    else
        mWidth = getMeasuredWidth();
    mPadding = 5;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    mPaint.setColor(Color.argb(100, 255, 255, 255));
    canvas.drawCircle(mWidth / 2, mWidth / 2, mWidth / 2 - mPadding, mPaint);
    mPaint.setColor(Color.WHITE);
    RectF rectF = new RectF(mPadding, mPadding, mWidth - mPadding, mWidth - mPadding);
    canvas.drawArc(rectF, startAngle, 100
            , false, mPaint);//第四个参数是否显示半径

}


private void initPaint() {
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setColor(Color.WHITE);
    mPaint.setStrokeWidth(8);
}

public void startAnim() {
    stopAnim();
    startViewAnim(0f, 1f, 1000);
}

public void stopAnim() {
    if (valueAnimator != null) {
        clearAnimation();
        valueAnimator.setRepeatCount(1);
        valueAnimator.cancel();
        valueAnimator.end();
    }
}

ValueAnimator valueAnimator;

private ValueAnimator startViewAnim(float startF, final float endF, long time) {
    valueAnimator = ValueAnimator.ofFloat(startF, endF);

    valueAnimator.setDuration(time);
    valueAnimator.setInterpolator(new LinearInterpolator());
    valueAnimator.setRepeatCount(ValueAnimator.INFINITE);//无限循环
    valueAnimator.setRepeatMode(ValueAnimator.RESTART);//

    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {

            float value = (float) valueAnimator.getAnimatedValue();
            startAngle = 360 * value;

            invalidate();
        }
    });
    valueAnimator.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
        }
    });
    if (!valueAnimator.isRunning()) {
        valueAnimator.start();
    }

    return valueAnimator;
}
}

Dialog代码:

public class LoadingDialog {
LVCircularRing mLoadingView;
Dialog mLoadingDialog;

public LoadingDialog(Context context,String msg) {
    // 首先得到整个View
    View view = LayoutInflater.from(context).inflate(
            R.layout.loading_dialog_view, null);
    // 获取整个布局
    LinearLayout layout = (LinearLayout) view.findViewById(R.id.dialog_view);
    // 页面中的LoadingView
    mLoadingView = (LVCircularRing) view.findViewById(R.id.lv_circularring);
    // 页面中显示文本
    TextView loadingText = (TextView) view.findViewById(R.id.loading_text);
    // 显示文本
    loadingText.setText(msg);
    // 创建自定义样式的Dialog
    mLoadingDialog = new Dialog(context, R.style.loading_dialog);
    // 设置返回键无效
    mLoadingDialog.setCancelable(false);
    mLoadingDialog.setContentView(layout, new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT,
            LinearLayout.LayoutParams.MATCH_PARENT));
}

public void show(){
    mLoadingDialog.show();
    mLoadingView.startAnim();
}

public void close(){
    if (mLoadingDialog!=null) {
        mLoadingView.stopAnim();
        mLoadingDialog.dismiss();
        mLoadingDialog=null;
    }
}
}

布局文件loading_dialog_view代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dialog_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="@drawable/dialog_bg"
android:padding="20dp"
android:orientation="vertical">

<com.ye.daqiapp.ui.widget.loading.LVCircularRing
    android:id="@+id/lv_circularring"
    android:layout_width="50dp"
    android:layout_height="50dp"/>

<TextView
    android:id="@+id/loading_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="#ffffff"
    android:layout_marginTop="5dp"
    android:textSize="15sp"/>

</LinearLayout>

Dialog中Style代码:

<style name="loading_dialog" parent="android:style/Theme.Dialog">
    <item name="android:windowFrame">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:backgroundDimEnabled">false</item>
    <item name="android:windowContentOverlay">@null</item>
</style>

背景dialog_bg代码

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 内部颜色 -->
<solid android:color="#444444" />

<!-- 圆角的幅度 -->
<corners
    android:bottomLeftRadius="3dp"
    android:bottomRightRadius="3dp"
    android:topLeftRadius="3dp"
    android:topRightRadius="3dp" />
</shape>

如何使用:
在需要使用的地方初始化Dialog:

LoadingDialog dialog=new LoadingDialog(context,"玩命加载中...");
//显示Dialog
dialog.show();
//关闭Dialog
dialog.close();

附上一些加载动画地址:
LoadingView

坚持原创技术分享,您的支持将鼓励我继续创作!