Android技术

自定义Android Dialog的另一种写法

2017-07-18  本文已影响0人  aositeluoke

一、需求分析

1、一款应用中,某样式的对话框只在一个Activity或Fragment中使用
2、一款应用中,某样式的对话框在多个Activity或Fragment中使用,只是文字不同,触发事件不同

二、详细分析

1、在构造方法中,指定布局和主题,可创建不同UI不同动画的Dialog
2、提供设置文字和设置点击事件的方法,解决需求分析中的第二个问题

三、完整代码

1、自定义Dialog代码

/**
 * 类描述:公共的对话框
 * 使用场景:应用中只有一个页面会用到这个UI的对话框
 * 初始化对话框时,提供一个对话框布局,一个主题(提供常用的两种,1、在屏幕中间透明度渐变显示 2、从下往上进入,从上往下退出)
 * 作者:xues
 * 时间:2017年07月17日
 */

public class CommonDialog extends AppCompatDialog {
    private volatile View mRootView;
    /**
     * 取消点击事件,关闭对话框
     */
    private final View.OnClickListener mCancelClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            dismiss();
        }
    };

    /**
     * @param context       Activity上下文对象,非Application
     * @param dialogThemeId 对话框主题
     * @param layoutId      布局id
     */
    public CommonDialog(Context context, @StyleRes int dialogThemeId, @LayoutRes int layoutId) {
        super(context, dialogThemeId);
        this.mRootView = LayoutInflater.from(context).inflate(layoutId, null);
        this.setContentView(this.mRootView);
    }

    /**
     * @param context       Activity上下文对象,非Application
     * @param dialogThemeId 对话框主题
     * @param layoutId      布局id
     * @param inBottom      是否在窗体的下方
     */
    public CommonDialog(Context context, @StyleRes int dialogThemeId, @LayoutRes int layoutId, boolean inBottom) {
        super(context, dialogThemeId);
        this.mRootView = LayoutInflater.from(context).inflate(layoutId, null);
        this.setContentView(this.mRootView);
//        设置对话框显示在窗体的最下方
        if (inBottom) {
            Window window = getWindow();
            window.setGravity(Gravity.BOTTOM); // 此处可以设置dialog显示的位置
            DisplayMetrics displayMetrics = new DisplayMetrics();
            window.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
            window.setLayout(displayMetrics.widthPixels, window.getAttributes().height);
        }
    }


    /**
     * 设置显示的文字
     *
     * @param viewID  控件id
     * @param content 字符串
     */
    public CommonDialog setText(@IdRes int viewID, String content) {
        try {
            TextView view = findViewByRootView(viewID);
            view.setText(content);
        } catch (Exception e) {
            throw new NullPointerException();
        }
        return this;
    }

    /**
     * 设置点击事件
     *
     * @param viewID        控件id
     * @param clickListener 点击事件
     */
    public CommonDialog setOnClickListener(@IdRes int viewID, View.OnClickListener clickListener) {
        View view = findViewByRootView(viewID);
        if (view == null) {
            throw new NullPointerException();
        } else {
            view.setOnClickListener(clickListener);
        }
        return this;
    }


    /**
     * 设置关闭对话框点击事件
     *
     * @param viewID 控件id
     */
    public CommonDialog setCloseDialogListener(@IdRes int viewID) {
        View view = findViewByRootView(viewID);
        if (view == null) {
            throw new NullPointerException();
        } else {
            view.setOnClickListener(mCancelClickListener);
        }
        return this;
    }


    /**
     * @param id  mRootView布局中的控件id
     * @param <T>
     * @return
     */
    public <T extends View> T findViewByRootView(@IdRes int id) {
        return (T) mRootView.findViewById(id);
    }
}

2、两种常用的主题

<!--[对话框主题]对话框会在屏幕中间显示-->
    <style name="dialog_theme_center_dispay" parent="@android:style/Theme.Dialog">
        <item name="android:windowFrame">@null</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:windowIsTranslucent">false</item>
        <item name="android:windowMinWidthMinor">100%</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowBackground">@color/transparent</item>
        <item name="android:backgroundDimEnabled">true</item>
        <item name="android:windowFullscreen">true</item>
        <item name="android:windowSoftInputMode">stateHidden|adjustResize</item>
    </style>

    <!--[对话框主题]对话框会从底部弹出-->
    <style name="dialog_theme_bottom2top">
        <item name="android:windowFrame">@null</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:windowIsTranslucent">false</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:layout_gravity">bottom</item>
        <item name="android:gravity">bottom</item>
        <item name="android:windowBackground">@color/transparent</item>
        <item name="android:backgroundDimEnabled">true</item>  <!--是否允许对话框的背景变暗?如果允许背景就变暗了。-->
        <item name="android:windowMinWidthMinor">100%</item><!--宽度铺满全屏-->
        <item name="android:windowCloseOnTouchOutside">true</item><!--点击阴影的地方是否可以关闭对话框-->
        <item name="android:windowAnimationStyle">@style/dialog_anim_bottom2top</item><!--对话框动画-->
        <item name="android:windowSoftInputMode">stateHidden|adjustResize</item>
    </style>

<!--[对话框动画]对话框会从底部弹出-->
    <style name="dialog_anim_bottom2top" parent="@android:style/Animation">
        <item name="android:windowEnterAnimation">@anim/push_bottom_in</item>
        <item name="android:windowExitAnimation">@anim/push_bottom_out</item>
    </style>

三、对话框从底部弹出的动画

1、push_bottom_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="500"
        android:fromYDelta="100%p"
        android:toYDelta="0" />

</set>
2、push_bottom_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="200"
        android:fromYDelta="0"
        android:toYDelta="50%p" />
    <alpha
        android:duration="200"
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />
</set>

四、使用篇

1、新建布局文件dialog_tip.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="@dimen/px520dp"
        android:layout_height="wrap_content"
        android:background="@color/white"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:paddingBottom="@dimen/px50dp"
            android:paddingTop="@dimen/px50dp"
            android:text="确定要取消订单吗?"
            android:textSize="@dimen/px36dp" />

        <View
            android:layout_width="match_parent"
            android:layout_height="@dimen/px1dp"
            android:background="#e1e1e1" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="@dimen/px92dp"
            android:orientation="horizontal">

            <Button
                android:id="@+id/btn_confirm"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="@color/white"
                android:text="确定" />

            <View
                android:layout_width="@dimen/px1dp"
                android:layout_height="match_parent"
                android:background="#e1e1e1" />

            <Button
                android:id="@+id/btn_cancel"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="@color/white"
                android:text="取消" />

        </LinearLayout>

    </LinearLayout>
</LinearLayout>

2、初始化对话框

 mCenterDialog = new CommonDialog(activity, R.style.dialog_theme_center_dispay, R.layout.dialog_tip);
        mCenterDialog.setText(R.id.tv_content, "您确定收到货物了吗?")
                .setCloseDialogListener(R.id.btn_cancel)
                .setOnClickListener(R.id.btn_confirm, new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        showMessage("确定按钮");
                    }
                });
上一篇 下一篇

猜你喜欢

热点阅读