您的位置:首页 > 移动开发 > Android开发

Android-- 封装Dialog,即自定义Dialog,使其满足各种dialog的样式要求

2016-12-09 15:12 579 查看
      工作中,我们免不了需要使用Dialog显示各种各样的提示页面,但是呢,有的需要透明度,有的需要取消黑暗度,或者对显示的位置和大小要求等等,不一而足,于是就产生

了自己封装一个高大上的Dialog来满足工作当中需要的各种各样的需求。

      其实呢,封装Dialog,最主要的地方就是在于dialog的Window的封装,通过getWindow获取到Window后,使用它可以对Dialog做一些自定义的内容。下面请看base类的代码:

import android.app.Dialog;

import android.content.Context;

import android.content.DialogInterface;

import android.os.Bundle;

import android.util.DisplayMetrics;

import android.view.Gravity;

import android.view.KeyEvent;

import android.view.LayoutInflater;

import android.view.MotionEvent;

import android.view.View;

import android.view.Window;

import android.view.WindowManager;

import com.creditease.ceinstallment.ui.activity.base.BaseActivity;

import com.creditease.chuangxin.yifenqi.R;

/**

 * Created by zgb on 2016/1/5.

 */

public abstract class BaseDialog extends Dialog implements DialogInterface.OnDismissListener {

    protected Context context;

    protected View localView;

    public static int mScreenWidth;

    public static int mScreenHeight;

    private float alpha = 1.0f;//背景透明度

    private float dim = 0.0f;//背景模糊度

    private int gravity = Gravity.CENTER;

    private boolean isAnimation = false;

    private boolean isWidth = false;//widthMargin传入的不是margin,而是真正的宽度值

    private int widthMargin = 0;

    private int height = WindowManager.LayoutParams.WRAP_CONTENT;

    public BaseDialog(Context context) {

        super(context);

        WindowManager wm = (WindowManager) getContext()

                .getSystemService(Context.WINDOW_SERVICE);

        DisplayMetrics metric = new DisplayMetrics();

        wm.getDefaultDisplay().getMetrics(metric);

        mScreenWidth = metric.widthPixels;

        mScreenHeight = metric.heightPixels;

        this.context = context;

        isAnimation =false;

    }

    public BaseDialog(Context context, int gravity) {

        this(context);

        this.gravity = gravity;

    }

    public BaseDialog(Context context, float alpha, float dim) {

        this(context);

        this.alpha = alpha;

        this.dim = dim;

    }

    public BaseDialog(Context context, int widthMargin, int height) {

        this(context);

        this.widthMargin = widthMargin;

        this.height = height;

    }

    public BaseDialog(Context context, int gravity, float alpha, float dim) {

        this(context);

        this.gravity = gravity;

        this.alpha = alpha;

        this.dim = dim;

    }

    public BaseDialog(Context context, int gravity, float alpha, float dim, boolean isAnimation) {

        this(context);

        this.gravity = gravity;

        this.alpha = alpha;

        this.dim = dim;

        this.isAnimation = isAnimation;

    }

    public BaseDialog(Context context, int widthMargin, int height, int gravity) {

        this(context);

        this.widthMargin = widthMargin;

        this.height = height;

        this.gravity = gravity;

    }

    public BaseDialog(Context context, int widthMargin, int height, int gravity, boolean isAnimation) {

        this(context);

        this.widthMargin = widthMargin;

        this.height = height;

        this.gravity = gravity;

        this.isAnimation = isAnimation;

    }

    public BaseDialog(Context context, int widthMargin, int height, int gravity, float alpha, float dim) {

        this(context);

        this.widthMargin = widthMargin;

        this.height = height;

        this.gravity = gravity;

        this.alpha = alpha;

        this.dim = dim;

    }

    public BaseDialog(Context context, int widthMargin, int height, int gravity, float alpha, float dim, boolean isAnimation) {

        this(context);

        this.widthMargin = widthMargin;

        this.height = height;

        this.gravity = gravity;

        this.alpha = alpha;

        this.dim = dim;

        this.isAnimation = isAnimation;

    }

    public BaseDialog(Context context, int widthMargin, int gravity, boolean isAnimation) {

        this(context);

        this.widthMargin = widthMargin;

        this.gravity = gravity;

        this.isAnimation = isAnimation;

    }

    public BaseDialog(Context context, int widthMargin, int height, int gravity, float alpha, float dim, boolean isAnimation,boolean isWidth) {

        this(context);

        this.widthMargin = widthMargin;

        this.height = height;

        this.gravity = gravity;

        this.alpha = alpha;

        this.dim = dim;

        this.isAnimation = isAnimation;

        this.isWidth = isWidth;

    }

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);

        // 这行代码换掉dialog默认背景,否则dialog的边缘发虚透明而且很宽

        // 总之达不到想要的效果

        getWindow().setBackgroundDrawableResource(android.R.color.transparent);

        LayoutInflater inflater = ((BaseActivity) context).getLayoutInflater();

        localView = inflater.inflate(getLayout(), null);

        setContentView(localView);

        //获取屏幕宽高

        WindowManager wm = (WindowManager) getContext()

                .getSystemService(Context.WINDOW_SERVICE);

        DisplayMetrics metric = new DisplayMetrics();

        wm.getDefaultDisplay().getMetrics(metric);

        mScreenWidth = metric.widthPixels;

        mScreenHeight = metric.heightPixels;

        //设置dialog的大小

        if(!isWidth){

            getWindow().setLayout(mScreenWidth - widthMargin, height);

        }else{

            getWindow().setLayout(widthMargin, height);

        }

        //设置dialog显示位置,居中、底部,顶部等等

        getWindow().setGravity(gravity);

        WindowManager.LayoutParams lp = getWindow().getAttributes();

        //设置dialog透明度

        lp.alpha = alpha;

        //设置dialog黑暗度,即除了内容之外的区域是否显示的黑暗度,0完全透明,1完全黑暗

        lp.dimAmount = dim;

        getWindow().setAttributes(lp);

        if (isAnimation) {

            getWindow().setWindowAnimations(R.style.dialogWindowAnim);

        }

        initView();

        initListener();

        s
4000
etOnDismissListener(this);

        setCanceledOnTouchOutside(setOutside());

        setOnKeyListener(new OnKeyListener() {

            @Override

            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {

                if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {

                    if(setKeyBack()){

                        dismiss();

                    }

                }

                return false;

            }

        });

    }

    @Override

    public boolean onTouchEvent(MotionEvent event) {

        return super.onTouchEvent(event);

    }

    /**

     * 获取到子类的布局

     * @return

     */

    protected abstract int getLayout();

    /**

     * 初始化View

     */

    protected abstract void initView();

    /**

     * 监听

     */

    protected abstract void initListener();

    /**

     * 设置点击dialog以外的地方是否可以dismiss

     * @return

     */

    protected boolean setOutside(){

        return true;

    }

    /**

     * 点击硬返回键时dialog以外的地方是否可以dismiss

     * @return

     */

    protected boolean setKeyBack(){

        return true;

    }

    public void showDialog() {

        show();

    }

    /**

     * dialog消失的时候可以做一些处理

     * @param dialogInterface

     */

    @Override

    public void onDismiss(DialogInterface dialogInterface) {

    }

}

代码中的注释写的还算可以,这里就做过多的解释了,唯一的不足的地方就是需要各种各样的构造方法去满足传入不同的参数,因为在new出dialog之前将参数实例化,否则onCreate方法不一定拿得到正确的参数值,会导致崩溃,我觉得这可能跟dialog的初始化流程有关,需要再仔细研究一下源码,或者为每个参数写一个protected的方法设置参数也是可以的。

下面是一个loading的dialog的具体实现,代码如下:

/**

 * Created by zgb on 2016/1/5.

 */

public class LoadingProgressDialog extends BaseDialog {

    private TextView titleView;

    private String title;

    private boolean isCanBack = true;

    private boolean isOutSide = true;

    public LoadingProgressDialog(Context context) {

        super(context, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, Gravity.CENTER, 0.7f, 0.0f, false, true);

        this.context = context;

    }

    public LoadingProgressDialog(Context context, String title) {

        this(context);

        this.title = title;

    }

    public LoadingProgressDialog(Context context, String title, boolean isOutSide, boolean isCanBack) {

        this(context, title);

        this.isOutSide = isOutSide;

        this.isCanBack = isCanBack;

    }

    @Override

    protected int getLayout() {

        return R.layout.dialog_loading_progress;

    }

    @Override

    protected void initListener() {

    }

    protected boolean setOutside() {

        return isOutSide;

    }

    protected boolean setKeyBack() {

        return isCanBack;

    }

    @Override

    protected void initView() {

        titleView = (TextView) localView.findViewById(R.id.progress_title);

        if (!TextUtils.isEmpty(title)) {

            titleView.setText(title);

        }

    }

    public void showDialog() {

        show();

    }

    @Override

    public void onBackPressed() {

        if (!isCanBack) {

            return;

        } else {

            super.onBackPressed();

        }

    }

}

dialog_loading_progress布局文件

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:layout_gravity="center"

    android:gravity="center"

    android:orientation="vertical"

    android:background="@drawable/dialog_loading_bg"

    android:padding="10dp"

     >

    <ProgressBar

        android:layout_width="22dp"

        android:layout_height="22dp"

        style="@style/style_progressbar"

        android:indeterminateDuration="700"

        />

    <TextView

        android:id="@+id/progress_title"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:textColor="@color/white"

        android:text="加载中"

        android:textSize="14sp"

        android:layout_marginTop="5dp"

        />

</LinearLayout>

dialog_loading_bg.xml布局文件

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="#000" />

    <corners

        android:bottomLeftRadius="5dp"

        android:bottomRightRadius="5dp"

        android:topLeftRadius="5dp"

        android:topRightRadius="5dp" />

</shape>

style_progressbar的style.xml中的配置

<style name="style_progressbar">

        <item name="android:indeterminateDrawable">@anim/rotate_progress</item>

          

        <item name="android:minWidth">22dp</item>

          

        <item name="android:maxWidth">44dp</item>

           

        <item name="android:minHeight">22dp</item>

          

        <item name="android:maxHeight">44dp</item>

    </style>

rotate_progress.xml的anim的动画文件

<?xml version="1.0" encoding="utf-8"?>

<rotate xmlns:android="http://schemas.android.com/apk/res/android"

    android:drawable="@drawable/loading_progress"

    android:fromDegrees="0"

    android:pivotX="50%"

    android:pivotY="50%"

    android:toDegrees="360"></rotate>

图片你可以任意找一个吧。

其实自己动手封装一些东西,不仅仅方便自己的开发,还能提高对软件架构的理解,也有利于更容易读懂安卓的源码,等等,好处多多吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android android开发