一、需求分析
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("确定按钮");
}
});