[仿南航app开发日记6]自定义背景透明进度条

前言

这篇博客是接着前面的那一篇 的:

[仿南航app开发日记5]查成绩界面开发完成以及使用PopupWindow踩过的坑

效果

这里写图片描述

源码与原理

既然是自定义透明对话框,那么我直接选择继承Dialog,然后创建对话框,先看源码:

package cn.karent.nanhang.UI;

import android.app.Dialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;

import cn.karent.nanhang.R;

/**
 * Created by wan on 2016/12/27.
 * 进度对话框
 */
public class ProgressDialog extends Dialog {

    private ProgressDialog(Context context) {
        super(context);
    }

    private ProgressDialog(Context context, int theme) {
        super(context, theme);
    }

    public static class Builder {

        private Context mContext;

        public Builder(Context context) {
            mContext = context;
        }


        public ProgressDialog create() {
            ProgressDialog p = new ProgressDialog(mContext, R.style.LoginDialogTheme);
            View v = LayoutInflater.from(mContext).inflate(R.layout.load_dialog_layout, null);
            p.addContentView(v, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            Window window  = p.getWindow();
            WindowManager.LayoutParams lp = window.getAttributes();
            lp.width = 700;
            lp.height = 700;
            window.setAttributes(lp);
            return p;
        }
    }


}

上面有定义高度和宽度,当然还设置了一个主题:

ProgressDialog p = new ProgressDialog(mContext, R.style.LoginDialogTheme);

至于这个主题,我在前面一篇创建登陆对话框时就使用过,我还是将sttyle放上来吧:

 <style name="LoginDialogTheme" parent="Theme.AppCompat.DayNight.Dialog">
        <item name="android:windowTitleStyle">@null</item>
        <item name="android:windowBackground">@null</item>
    </style>

这个style的功能就是去除了背景和标题,当然了,上面是继承Dialog,但是必须要自己写布局啊,布局如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <LinearLayout
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <cn.karent.nanhang.UI.ProgressView
            android:id="@+id/load_dialog_progressView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:layout_marginTop="10dp"
            android:text="正在加载中。。。"
            android:textColor="#dfdbdb"/>
    </LinearLayout>
</RelativeLayout>

依然是比较普通的布局文件,其中使用了一个自定义类,那就是

cn.karent.nanhang.UI.ProgressView

这个就是自定义进度条的核心了,我们看下源码:

package cn.karent.nanhang.UI;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.PorterDuff;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.View;
import cn.karent.nanhang.R;

/**
 * Created by wan on 2016/12/27.
 * 重复绘制小圆点
 */
public class ProgressView extends View {
    /**
     * 全局上下文
     */
    private Context mContext;
    /**
     * 图像变换矩阵
     */
    private Matrix mMatrix = new Matrix();
    /**
     * 要绘制的背景图,也就是那个旋转的点点
     */
    private Bitmap mBitmap;
    /**
     * 图片的宽度
     */
    private int mWidth;
    /**
     * 图片的宽度
     */
    private int mHeight;

    public ProgressView(Context context) {
        super(context);
    }

    public ProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        //从资源加载bitmap对象
        mBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.pic_dlg_loading);
        mWidth = mBitmap.getWidth();
        mHeight = mBitmap.getHeight();
        //执行循环
        new LoopAnimation().execute();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(mWidth, mHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        mMatrix.preRotate(6, mWidth / 2, mHeight / 2);
        canvas.drawBitmap(mBitmap, mMatrix, null);
    }

    /**
     * 循环动画,不停的触发旋转动画
     */
    class LoopAnimation extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
            invalidate();
        }

        @Override
        protected Void doInBackground(Void... params) {
            int rotate = 0;
            while( true ) {
                try {
                    Thread.sleep(100);
                } catch(InterruptedException e) {
                    e.printStackTrace();
                }
                publishProgress();
            }
        }
    }

}

看到了没,原理就是开个线程,然后不断的绘制一张图片,这里面有几点需要注意的地方:

 mMatrix.preRotate(6, mWidth / 2, mHeight / 2);

这个是旋转的代码,必须知道图片的中心 (后面那两个参数),否则将会以原点为中心旋转,得到的结果绝对不是你想要的,另外还有一点需要注意,因为我们前面将对话框的背景去掉,所以默认不会清楚画布上面的内容,画出来的图形是不断叠加,在普通的java绘图当中我们的做法是在绘制任何东西之前先绘制一个白色背景,但是这里我们要绘制一个透明的背景:

canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

这样就会清除原先绘制的背景 从而重新绘制了,好了,要点就是这么多。
我现在的测试的是直接在Activity的onCreate方法里面创建对话框,真正使用的时候可以先创建,然后在访问网络完成将对话框dismiss掉,代码如下:

 new ProgressDialog.Builder(this).create().show();

上面的加载的是再ScoreActivity的onCreate方法里面,至于ScoreActivity是什么,我前面一篇博客有讲

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值