DialogFragment 从底部弹出对话框 动态设置高度拷贝代码直接用

xiaoxiao2021-02-28  63

文章目录

效果图需求思路实现抽象类实现动画和主题隐藏动画主题 另外 虚拟导航栏导致高度计算错误问题调用

效果图

需求

现在需要实现 底部弹出对话框 并且 弹出的高度 需要刚好在顶部的一个view下面. 这个view的高度不确定.

思路

整个window的高度减去顶部标题栏和这个view的高度 就是这个对话框的高度

实现

动态传递参数进入dialogFragment 然后动态设置dialogFragment的高度

抽象类

public abstract class BottomDialog extends DialogFragment { @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); //设置style setStyle(DialogFragment.STYLE_NORMAL, R.style.BottomDialog); } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { //去除标题栏 getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE); Window window = getDialog().getWindow(); WindowManager.LayoutParams lp = window.getAttributes(); lp.gravity = Gravity.BOTTOM; //底部 lp.width = WindowManager.LayoutParams.MATCH_PARENT; window.setAttributes(lp); return createView(inflater, container); } //重写此方法,设置布局文件 protected abstract View createView(LayoutInflater inflater, ViewGroup container); }

实现

/** * @author liumaolin * @explain * @time 2018/7/6 17:17 */ public class MyDialogFragment extends BottomDialog { public DialogInterface dialogInterface; public Activity activity; private View inflate; private int height; private static final String ARG_PARAM1 = "param1"; private static final String ARG_PARAM2 = "param2"; private String string; public static final MyDialogFragment newInstance(int param1) { MyDialogFragment fragment = new MyDialogFragment(); Bundle args = new Bundle(); args.putInt(ARG_PARAM1, param1); fragment.setArguments(args); return fragment; } public void setInterface(DialogInterface dialogInterface) { this.dialogInterface = dialogInterface; } @Override public void onStart() { super.onStart(); //设置 dialog 的宽高 if (height > 0) { getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, height); } else { getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); } //设置 dialog 的背景为 null getDialog().getWindow().setBackgroundDrawable(null); } public void setActivity(Activity activity) { this.activity = activity; } @Override protected View createView(LayoutInflater inflater, ViewGroup container) { if (getArguments() != null) { height = getArguments().getInt(ARG_PARAM1); LogUtil.d("传递过来的 = " + string); } //这里设置dialogfragment 的布局 inflate = inflater.inflate(R.layout.dialog_fragment, container); TextView viewById = inflate.findViewById(R.id.tv_login); viewById.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { PictureDialog pictureDialog = new PictureDialog(getActivity(), R.style.CustomAlertDialog); Window win = pictureDialog.getWindow(); win.setGravity(Gravity.BOTTOM); pictureDialog.show(); } }); LogUtils.d("获取高度:" + height); if (height > 0) { View view = inflate.findViewById(R.id.ll_contener); view.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height)); } return inflate; } // }

动画和主题

展示

bottom_dialog_slide_show

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="@android:integer/config_mediumAnimTime" android:fromYDelta="100%p" android:toYDelta="0%p" /> </set>

隐藏动画

bottom_dialog_slide_hide

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="@android:integer/config_mediumAnimTime" android:fromYDelta="0%p" android:toYDelta="100%p" /> </set>

主题

<style name="BottomDialog" parent="Theme.AppCompat.Light.Dialog"> <item name="android:windowAnimationStyle">@style/BottomDialogAnimation</item> <item name="android:backgroundDimEnabled">false</item><!--不变暗--> </style> <style name="BottomDialogAnimation"> <item name="android:windowEnterAnimation">@anim/bottom_dialog_slide_show</item> <item name="android:windowExitAnimation">@anim/bottom_dialog_slide_hide</item> </style>

另外 虚拟导航栏导致高度计算错误问题

/** * 计算dialog 高度 */ private void countHeight() { llTop.measure(0, 0); //获取顶部组件高度 int height = llTop.getMeasuredHeight(); LogUtil.d("\n顶部高度 =:" + height); int heightDisplay = AppUtils.getHeightDisplay(); LogUtil.d("\n屏幕高度 =:" + heightDisplay); int daoHangHeight = getDaoHangHeight(getActivity()); LogUtil.d("\n导航栏高度 =:" + daoHangHeight); if (isNavigationBarShow()) { bottomHeight = heightDisplay - height; } else { bottomHeight = heightDisplay - height + daoHangHeight; } LogUtil.d("\n对话框高度 =:" + bottomHeight); // return bottomHeight; } /** * 判断是否显示虚拟导航栏 * @return */ public boolean isNavigationBarShow() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); Point realSize = new Point(); display.getSize(size); display.getRealSize(realSize); return realSize.y != size.y; } else { boolean menu = ViewConfiguration.get(this).hasPermanentMenuKey(); boolean back = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK); if (menu || back) { return false; } else { return true; } } } /** * 获取导航栏高度 * * @param context * @return */ public static int getDaoHangHeight(Context context) { int result = 0; int resourceId = 0; int rid = context.getResources().getIdentifier("config_showNavigationBar", "bool", "android"); if (rid != 0) { resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android"); int dimensionPixelSize = context.getResources().getDimensionPixelSize(resourceId); return dimensionPixelSize; } else return 0; }

调用

private void showDialog() { countHeight(); MyDialogFragment.newInstance(bottomHeight).show(getSupportFragmentManager(),"tag"); }
转载请注明原文地址: https://www.6miu.com/read-2625056.html

最新回复(0)