安卓自定义Dialog - 使用DialogFragment
可以实现的效果图:
居中效果
底部效果,可以自适应高度或使用布局文件dp高度,也可以自行设置固定屏幕4/5高度等等,可以实现底部弹出效果,动画可以参考下方代码
封装DialogFragment实现自定义样式的Dialog
抽象类 BaseDialogFragment 代码
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
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.view.inputmethod.InputMethodManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import java.util.Objects;
public abstract class BaseDialogFragment extends DialogFragment {
protected Context mContext;
protected View view;
private final DialogPosition dialogPosition;
private final boolean canceledOnTouchOutside;
/**
* 初始化器
*
* @param dialogPosition Dialog位置
* @param canceledOnTouchOutside 点击外部是否关闭Dialog
*/
public BaseDialogFragment(DialogPosition dialogPosition, boolean canceledOnTouchOutside) {
this.dialogPosition = dialogPosition;
this.canceledOnTouchOutside = canceledOnTouchOutside;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
Window window = Objects.requireNonNull(getDialog()).getWindow();
window.getDecorView().setPadding(0, 0, 0, 0);
WindowManager.LayoutParams attributes = window.getAttributes();
switch (dialogPosition) { // Dialog位置
case CENTER:
attributes.width = WindowManager.LayoutParams.WRAP_CONTENT;
attributes.height = WindowManager.LayoutParams.WRAP_CONTENT;
attributes.gravity = Gravity.CENTER;
break;
case BOTTOM: // 底部Dialog的宽度会自动适应全屏
attributes.width = WindowManager.LayoutParams.MATCH_PARENT;
attributes.height = WindowManager.LayoutParams.WRAP_CONTENT;
attributes.gravity = Gravity.BOTTOM;
break;
}
window.setAttributes(attributes);
super.onActivityCreated(savedInstanceState);
}
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
Dialog dialog = new Dialog(getActivity(), getDialogStyleId());
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); // 去掉标题栏
dialog.setCanceledOnTouchOutside(canceledOnTouchOutside); // 点击外部是否关闭Dialog
return dialog;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(getLayoutId(), container, false);
mContext = getActivity();
this.initView();
this.initData();
this.initListener();
return view;
}
/**
* 布局Id
*/
protected abstract int getLayoutId();
/**
* Dialog样式Id
*/
protected abstract int getDialogStyleId();
/**
* 初始化View
*/
protected abstract void initView();
/**
* 初始化数据
*/
protected abstract void initData();
/**
* 初始化监听器
*/
protected abstract void initListener();
/**
* Dialog位置
* CENTER:居中
* BOTTOM:底部
*/
public enum DialogPosition {
CENTER, BOTTOM
}
/**
* 弹出软键盘
* PS:若要使用此方法自动弹出软键盘,dialog样式必须配置<item name="android:windowSoftInputMode">stateVisible</item>
*/
public void openKeyboard(View view) {
// 获取焦点
view.setFocusable(true);
view.setFocusableInTouchMode(true);
view.requestFocus();
// 弹出软键盘
InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}
}
提供几种dialog样式配置
<!-- 基础dialog样式-->
<style name="MyDialogStyle">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">true</item> <!-- 背景是否变灰 -->
<item name="android:windowBackground">@android:color/transparent</item>
</style>
<!-- 允许自动弹出输入框的dialog-->
<style name="MyEditTextDialog" parent="MyDialogStyle">
<item name="android:windowSoftInputMode">stateVisible</item>
</style>
<!-- 从底部弹出的动画dialog-->
<style name="MyBottomDialog" parent="MyDialogStyle">
<item name="android:windowAnimationStyle">@style/centerDialogStyle</item>
</style>
<style name="centerDialogStyle">
<item name="android:windowEnterAnimation">@anim/dialog_fr_in</item>
<item name="android:windowExitAnimation">@anim/dialog_fr_out</item>
</style>
dialog_fr_in.xml 代码
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="200"
android:fromYDelta="100%"
android:toYDelta="0">
</translate>
dialog_fr_out.xml 代码
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="200"
android:fromYDelta="0"
android:toYDelta="100%">
</translate>