通常我们只需要关注三个回调方法:
onCreateDialog:创建一个dialog外壳
onCreateView:给dialog外壳填充自己想要的样式布局
onViewCreated:这里面给布局的view进行初始化操作,可以设置一些监听器等等
自定义布局文件:随便写一个
selfFragment类:
package com.example.hellojni;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
public class selfDialogFragment extends DialogFragment {
View container;
@NonNull@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
return new Dialog(getContext(),R.style.bottom_dialog);
// return super.onCreateDialog(savedInstanceState);//不采用系统默认的dialog样式,自定义dialog主题
}
@Nullable@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Window window = getDialog().getWindow();
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,WindowManager.LayoutParams.WRAP_CONTENT);
window.setGravity(Gravity.CENTER);//设置dialog位置处于中央if(!iPaid(getContext())){
window.getDecorView().setMinimumWidth(getResources().getDisplayMetrics().widthPixels);//这个设置的目的是为了让dialog横向宽度是充满屏幕的
}
// window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);//本来想解决dialog打开软键盘后,弹窗跟着往上走的效果,效果确实有,不过依然没有解决我的问题,下面会详解。
return inflater.inflate(R.layout.dialog_block_reason,container,false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
View dialogViewContent = view.findViewById(R.id.block_number_container);
EditText editText = view.findViewById(R.id.optional_block_number);
container = view.findViewById(R.id.block_number_container);
editText.requestFocus();
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
dialogViewContent.setOnTouchListener(new View.OnTouchListener() {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
//强制收起软件盘的方式:
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(),0);
return false;
}
});
view.findViewById(R.id.cancel_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismissAllowingStateLoss();
hideSoftInputAndDissmissDialog();
}
});
private void hideSoftInputAndDissmissDialog() {
dismissAllowingStateLoss();
if (getActivity() != null) {//为了解决dialog弹出软键盘退出界面后软键盘依然存在的问题getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
}
@Override
public void onStart() {
super.onStart();
}
//判断是否为Pad的方法,通过计算屏幕对角线长度
private boolean isPad(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Displaydisplay = wm.getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
display.getMetrics(dm);
double x = Math.pow(dm.widthPixels / dm.xdpi, 2);
double y = Math.pow(dm.heightPixels / dm.ydpi, 2);
double screenInches = Math.sqrt(x + y); // 屏幕尺寸
return screenInches >= 7.0;
}
}
坑点讲解
当dialog有editText的时候,如果你的dialog主题中的
当android:windowIsFloating设为true时,效果如下:
不过中间多出来的那块我也不知道受什么因素影响的,目前这个样式还能凑活用吧
默认的dialog并非是横向充满屏幕的 我这边用了使用了window.getDecorView().setMinimumWidth(getResources().getDisplayMetrics().widthPixels);生效了,有的博客说是使用 window.getDecorView().setPadding(0,0,0,0)或者主题中有个属性android:windowFullscree,不过这两个我试过都貌似都没有什么效果
当打开软键盘,然后点击空白处的时候,dialog消失,但是软键盘却还是打开着。
这个点我使用了getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);解决了,这句话等同于在展示dialog的activity中androidMenifests文件中设置andorid:windowSoftInputMode = stateAlwaysHidden,而仅仅设置成stateHidden是不够的,具体这两个参数的详细区别,官方文档说的也很含糊,反正我没读懂。
我比较认同这篇文章的看法:blog.csdn.net/mqdxiaoxiao…
默认的dialog出场以及退场动画是采用了缩放以及透明度,可以在主题中自定义出场动画enter动画:
exit动画:
通常只需要关注onCreate方法,在该方法中,一般需要做如下几个事情:
通过setContentView将自定义的布局填充到dialog中去
初始化布局中的子view,并设置监听器,事件响应等
初始化window相关的属性,比如设置window的宽度和高度,以及window所显示的位置等等
在构造函数中设置想要的主题:这里提供两种比较常用的主题
bottom_in:
bottom_out:
辨别当前设备是否是平板的方法通常有两种:
publicstaticbooleanisLargeScreen(Context context){
Configuration config = context.getResources().getConfiguration();
int size = config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
return (size >= Configuration.SCREENLAYOUT_SIZE_LARGE);
}
public static boolean isPad(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
display.getMetrics(dm);
double x = Math.pow(dm.widthPixels / dm.xdpi, 2);
double y = Math.pow(dm.heightPixels / dm.ydpi, 2);
double screenInches = Math.sqrt(x + y); // 屏幕尺寸
return screenInches >= 7.0;
}