为适配平板而生的Dialog(同样也支持手机)

专为平板而生的Dialog(同样也支持手机)

因公司的业务需求变动,由手机开发转为手机,平板一起开发!导致项目之前写的Dialog在平板上出现很多兼容性问题,没办法只能一个一个的改了!但是,一查看代码发现,有太多太多的Dialog需要改动了,于是乎,为适配平板的Dialog基类(同样适用于手机端)就横空出世了!

特点

  • 支持横竖屏切换
  • 支持修改Dialog的宽高
  • 支持修改Dialog的动画,样式
  • 默认三种状态

BaseDialog代码如下

import android.app.Dialog;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Point;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.BottomSheetDialog;
import android.support.v7.app.AppCompatDialogFragment;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;

import com.app.myview.R;

public abstract class BaseDialog extends AppCompatDialogFragment implements View.OnClickListener,
        AdapterView.OnItemClickListener {

    /** 默认的Style */
    final static int DIALOG_DEFAULT_STYLE = R.style.dialogStyle;
    /** 弹窗的类型  */
    protected int dialogType = -1;
    /** 底部弹出   */
    protected final static int DIALOG_BOTTOM = 0x0;
    /** 顶部弹出   */
    protected final static int DIALOG_TOP = 0x1;
    /** 中心弹出   */
    protected final static int DIALOG_CENTER = 0x2;

    /** 默认弹窗的高  */
    protected final static int DIALOG_DEFAULT_HEIGHT = ViewGroup.LayoutParams.WRAP_CONTENT;
    /** 默认弹窗的宽  */
    protected final static int DIALOG_DEFAULT_WIDTH = ViewGroup.LayoutParams.WRAP_CONTENT;

    /** 根视图   */
    protected View rootView;

    protected DialogChildClickListener listener;
    public void setDialogItemClickListener(DialogChildClickListener listener) {
        this.listener = listener;
    }

    @Override
    public final Dialog onCreateDialog(Bundle savedInstanceState) {
        int type = getDialogType();
        switch (type) {
            case DIALOG_BOTTOM:
                dialogType = DIALOG_BOTTOM;
                /**
                 *  也可以这样 底部弹出的
                 */
               // return getDialogByType(getStyle(), DIALOG_BOTTOM);
                return new BottomSheetDialog(getContext(), getTheme());
            case DIALOG_CENTER:
                dialogType = DIALOG_CENTER;
                return new Dialog(getContext(), getStyle());
            case DIALOG_TOP:
                dialogType = DIALOG_TOP;
                return getDialogByType(getStyle(), DIALOG_TOP);
            default:
                return super.onCreateDialog(savedInstanceState);
        }
    }

    @Nullable
    @Override
    public final View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        int layoutID = getDialogView();
        if (layoutID <= 0) {
            throw new NullPointerException("Dialog layout is not null");
        } else {
            rootView = inflater.inflate(layoutID, container, false);
        }
        return rootView;
    }

    @Override
    public final void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        initDialog(view, savedInstanceState);
    }

    @Override
    public void onStart() {
        super.onStart();
        setDialogProperty();
    }

    /** 获取弹窗的style,0默认为{@link #DIALOG_DEFAULT_STYLE} */
    protected abstract int getDialogStyle();
    /** 获取弹窗的类型 三种状态 DIALOG_BOTTOM,DIALOG_TOP,DIALOG_CENTER */
    protected abstract int getDialogType();
    /** 获取弹窗的Layout */
    protected abstract int getDialogView();
    /** 初始化弹窗  */
    protected abstract void initDialog(View view, Bundle bundle);
    /** 设置弹窗的属性,比如宽、高,动画等  */
    protected abstract void setDialogProperty();
    /** 切换竖屏调用此方法  */
    protected abstract void changePORTRAIT();
    /** 切换横屏调用此方法  */
    protected abstract void changeLANDSCAPE();
    /** 销毁  */
    protected abstract void destroyAll();

    /**
     * 设置Dialog的宽高
     * width 默认为{@link #DIALOG_DEFAULT_WIDTH}
     * height 默认为{@link #DIALOG_DEFAULT_HEIGHT}
     */
    protected final void setDialogWH() {
        // 底部弹窗Dialog宽度默认为屏幕的宽度,或者根据自己需求改动
        if (dialogType == DIALOG_BOTTOM) {
            return;
        }
        Window window = getDialog().getWindow();
        window.setLayout(DIALOG_DEFAULT_WIDTH, DIALOG_DEFAULT_HEIGHT);
    }

    /**
     * 设置Dialog的宽高
     * @param width  宽
     * @param height 高
     */
    protected final void setDialogWH(int width, int height) {
        if (dialogType == DIALOG_BOTTOM) {
            return;
        }
        if (width <= 0) {
            throw new RuntimeException("Dialog width cannot be less than 0! You might need the setDialogWH () method");
        }
        if (height <= 0) {
            throw new RuntimeException("Dialog height cannot be less than 0! You might need the setDialogWH () method");
        }
        Window window = getDialog().getWindow();
        window.setLayout(width, height);
    }

    /**
     * 得到Display
     * @return Display
     */
    protected final Display getDisplay() {
        WindowManager manager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        return manager.getDefaultDisplay();
    }

    /**
     * 得到屏幕的宽度
     * @return width
     */
    protected final int getWidth() {
        Point point = new Point();
        getDisplay().getSize(point);
        return point.x;
    }

    /**
     * 设置Dialog的进出动画
     */
    protected final void setDialogAnim(int resId) {
        getDialog().getWindow().setWindowAnimations(resId);
    }

    /**
     * findViewById
     */
    protected final <V extends View> V $(int id) {
        if (rootView == null) throw new NullPointerException("rootView is not null!");
        return (V) rootView.findViewById(id);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            changeLANDSCAPE();
        } else {
            changePORTRAIT();
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        destroyAll();
    }

    @Override
    public void onClick(View v) {

    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

    }

    private int getStyle() {
        int style = getDialogStyle();
        return style <= 0 ? DIALOG_DEFAULT_STYLE : style;
    }

    private Dialog getDialogByType (int dialogType, int type) {
        Dialog dialog = new Dialog(getContext(), dialogType);
        Window window = dialog.getWindow();
        if (window != null) {
            if(type == DIALOG_TOP) {
                window.setGravity(Gravity.TOP);
            } else if (type == DIALOG_BOTTOM) {
                window.setGravity(Gravity.BOTTOM);
            }
        }
        return dialog;
    }

    public interface DialogChildClickListener {

        /**
         * Dialog点击事件
         * @param view   当前视图
         * @param values 任意类型的值
         */
        void childClick(View view, Object... values);
    }
}

默认的Dialog样式

<style name="dialogStyle">
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowFrame">@null</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:backgroundDimEnabled">true</item>
    </style>

PS:谷歌官方也推荐使用DialogFragment来创建Dialog

如何使用

// 继承BaseDialog,实现里面的抽象方法,layout_dialog布局文件就不发了
public class TestDialog extends BaseDialog {

    public static TestDialog newInstance() {

        Bundle args = new Bundle();

        TestDialog fragment = new TestDialog();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    protected int getDialogStyle() {
        // 弹窗Style
        return 0;
    }

    @Override
    protected int getDialogType() {
        // 弹窗类型
        return DIALOG_CENTER;
    }

    @Override
    protected int getDialogView() {
        // 弹窗布局
        return R.layout.layout_dialog;
    }

    @Override
    protected void initDialog(View view, Bundle bundle) {
        $(R.id.dialog_ok).setOnClickListener(this);
        $(R.id.dialog_cancel).setOnClickListener(this);
    }

    @Override
    protected void setDialogProperty() {
        setDialogAnim(android.R.style.Animation_Translucent);
    }

    @Override
    protected void changePORTRAIT() {
        L.e("切换至竖屏");
        setDialogWH();
    }

    @Override
    protected void changeLANDSCAPE() {
        L.e("切换至横屏");
        setDialogWH(getWidth(), 600);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        switch (id) {
            case R.id.dialog_ok:
                if (listener != null) {
                    listener.childClick(v, id);
                }
                break;
            case R.id.dialog_cancel:
                Toaster.makeText("Dialog自己处理点击事件");
                break;
        }
        dismiss();
    }

    @Override
    protected void destroyAll() {
        L.e("销毁Dialog");
    }
}

Activity中

/**
 * DialogActivity 布局就不发了
 * 注意:DialogActivity一定要继承FragmentActivity
 * 屏幕旋转,需要给DialogActivity设置android:configChanges="orientation|keyboardHidden|screenSize"
 */
public class DialogActivity extends FragmentActivity implements BaseDialog.DialogChildClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dialog);

        findViewById(R.id.button5).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 不需要传值给Dialog
                TestDialog dialog = new TestDialog();
                // 传值给Dialog
//                TestDialog dialog1 = TestDialog.newInstance();

                Fragment fragment = getSupportFragmentManager().findFragmentByTag("testDialog");
                if (fragment != null) {
                    //为了不重复显示dialog,在显示对话框之前移除正在显示的对话框
                    getSupportFragmentManager().beginTransaction().remove(fragment).commit();
                }

                // Dialog与Activity交互
                dialog.setDialogItemClickListener(DialogActivity.this);
                // 显示Dialog
                dialog.show(getSupportFragmentManager(), "testDialog");
            }
        });
    }

    @Override
    public void childClick(View view, Object... values) {
        int id = view.getId();
        switch (id) {
            case R.id.dialog_ok:
                Toaster.makeText("Activity处理Dialog点击事件");
                break;
        }
    }

}

DialogActivity 布局就不发了!注意:DialogActivity一定要继承FragmentActivity。屏幕旋转,需要给DialogActivity设置android:configChanges=”orientation|keyboardHidden|screenSize”

没图我说个,下面是效果图,请忽略掉横屏时的样式问题!

这里写图片描述

写得不好呀,勿喷

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值