如果您直接从资源值转换:
int width = getResources().getDimensionPixelSize(R.dimen.popup_width); int height = getResources().getDimensionPixelSize(R.dimen.popup_height); getDialog().getWindow().setLayout(width, height);
然后在对话框的布局中指定match_parent:
android:layout_width="match_parent" android:layout_height="match_parent"
你只需要担心一个地方(把它放在你的DialogFragment#onResume )。 它不完美,但至less它有一个RelativeLayout作为对话框的布局文件的根。
我有一个固定大小的DialogFragment,在XML主布局中定义了以下内容(在我的情况下是LinearLayout):
android:layout_width="match_parent" android:layout_height="match_parent" android:minWidth="1000dp" android:minHeight="450dp"
我最终重写了Fragment.onResume()并从底层对话框中获取属性,然后在那里设置宽度/高度参数。 我将最外面的布局高度/宽度设置为match_parent 。 请注意,此代码似乎也尊重我在xml布局中定义的边距。
@Override public void onResume() { ViewGroup.LayoutParams params = getDialog().getWindow().getAttributes(); params.width = LayoutParams.MATCH_PARENT; params.height = LayoutParams.MATCH_PARENT; getDialog().getWindow().setAttributes((android.view.WindowManager.LayoutParams) params); super.onResume(); }
在我的情况下工作的唯一的东西是在这里指出的解决scheme: http : //adilatwork.blogspot.mx/2012/11/android-dialogfragment-dialog-sizing.html
Adil博客文章片段:
@Override public void onStart() { super.onStart(); // safety check if (getDialog() == null) return; int dialogWidth = ... // specify a value here int dialogHeight = ... // specify a value here getDialog().getWindow().setLayout(dialogWidth, dialogHeight); // ... other stuff you want to do in your onStart() method }
我试图让对话尊重我的布局的宽度和高度,没有以编程方式指定一个固定的大小。
我想, android:windowMinWidthMinor和android:windowMinWidthMajor是造成这个问题。 即使它们不包含在我的Activity或Dialog的主题中,它们仍然以某种方式应用于Activity主题。
我想出了三种可能的解决scheme。
解决scheme1:创build自定义对话框主题,并在DialogFragment创build对话框时使用它。
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { return new Dialog(getActivity(), R.style.Theme_Material_Light_Dialog_NoMinWidth); }
解决scheme2:创build一个用于ContextThemeWrapper的自定义主题,该主题将用作对话框的Context 。 如果您不想创build自定义对话框主题(例如,当您想使用由android:dialogTheme指定的主题),请使用此android:dialogTheme 。
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { return new Dialog(new ContextThemeWrapper(getActivity(), R.style.Theme_Window_NoMinWidth), getTheme()); }
解决scheme3(带有AlertDialog ):在AlertDialog$Builder创build的AlertDialog$Builder强制执行android:windowMinWidthMinor和android:windowMinWidthMajor 。
@Override public final Dialog onCreateDialog(Bundle savedInstanceState) { View view = new View(); // Inflate your view here. AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setView(view); // Make sure the dialog width works as WRAP_CONTENT. builder.getContext().getTheme().applyStyle(R.style.Theme_Window_NoMinWidth, true); return builder.create(); }
DialogFragment #13: DialogFragment布局
这真是麻木的。
当创build一个DialogFragment ,你可以select覆盖onCreateView (它传递一个ViewGroup来附加你的.xml布局)或onCreateDialog ,而不是。
你不能重写这两个方法,因为你很可能会混淆Android时,或者如果你的对话框的布局膨胀! WTF?
是否重写OnCreateDialog或OnCreateView取决于您打算如何使用对话框。
这可能是世界上最糟糕的事情。
onCreateDialog疯狂
因此,您在DialogFragment重写DialogFragment以创build一个DialogFragment的自定义实例以显示在窗口中。 凉。 但请记住, onCreateDialog不会收到任何ViewGroup以将自定义的.xml布局附加到 。 没问题,只需将null传递给inflate方法。
让疯狂开始。
当你重写onCreateDialog ,Android COMPLETELY IGNORES会膨胀.xml布局根节点的几个属性。 这包括但不限于:
这几乎是滑稽的,因为您需要设置每个.xml布局的layout_width和layout_height ,否则Android Studio会用一个可爱的小红帽来鞭打你。
DialogFragment这个词让我想呕吐。 我可以写一本充满Android陷阱和snafus的小说,但是这是一个最内在的。
为了回到理智状态,首先,我们声明一个样式来恢复我们期望的background_color和layout_gravity :
上面的样式inheritance自对话框的基本主题(在本例中是AppCompat主题)。
接下来,我们通过编程的方式来应用样式,以恢复Android刚刚抛弃的值,并恢复标准的AlertDialog外观:
public class MyDialog extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { View layout = getActivity().getLayoutInflater().inflate(R.layout.my_dialog_layout, null, false); assert layout != null; //build the alert dialog child of this fragment AlertDialog.Builder b = new AlertDialog.Builder(getActivity()); //restore the background_color and layout_gravity that Android strips b.getContext().getTheme().applyStyle(R.style.MyAlertDialog, true); b.setView(layout); return b.create(); } }
上面的代码将使AlertDialog再次像AlertDialog一样。 也许这是够好的。
但是等等,还有更多!
如果你正在为你的AlertDialog设置一个特定的 layout_width或layout_height ,当它显示(非常可能),那么猜测你还没有完成!
随着你意识到,如果你试图用你自己喜欢的新风格来设置一个特定的layout_width或者layout_height ,那么这个欢闹会继续,Android也会完全忽略这个!
要设置一个特定的窗口宽度或高度,你可以进入一个完整的方法,处理LayoutParams :
@Override public void onResume() { super.onResume(); Window window = getDialog().getWindow(); if(window == null) return; WindowManager.LayoutParams params = window.getAttributes(); params.width = 400; params.height = 400; window.setAttributes(params); }
许多人遵循Android的糟糕的例子,将WindowManager.LayoutParams强制转换为更一般的ViewGroup.LayoutParams ,只是右转,然后将ViewGroup.LayoutParams强制转换回WindowManager.LayoutParams 。 有效的Java是该死的,除了使代码更难破译以外,不必要的铸造只能提供任何东西。
附注:在Android SDK中有几十次LayoutParams重复 – 这是devise极其糟糕的完美例子。
综上所述
对于覆盖onCreateDialog DialogFragment :
当我需要使DialogFragment更宽一点时我设置minWidth:
我修复了它设置根元素布局参数。
int width = activity.getResources().getDisplayMetrics().widthPixels; int height = activity.getResources().getDisplayMetrics().heightPixels; content.setLayoutParams(new LinearLayout.LayoutParams(width, height));
这是一个设置xml中的DialogFragment宽度/高度的方法。 只需将您的viewHierarchy包装在一个Framelayout(任何布局将工作)与透明背景。
透明的背景似乎是一个特殊的标志,因为当你这样做的时候,它会自动将frameLayout的子项放到窗口中。 你仍然会得到你的片段后面全屏变暗,表明你的片段是主动元素。
<?xml version="1.0" encoding="utf-8"?> .....
最外层布局中的维度在对话框中不起作用。 您可以添加一个布局,其中在最外层以下设置尺寸。
我使用AlertDialog.Builder创build对话框,所以我在一个OnShowListener中使用了Rodrigo的答案。
dialog.setOnShowListener(new OnShowListener() { @Override public void onShow(DialogInterface dialogInterface) { Display display = getWindowManager().getDefaultDisplay(); DisplayMetrics outMetrics = new DisplayMetrics (); display.getMetrics(outMetrics); dialog.getWindow().setLayout((int)(312 * outMetrics.density), (int)(436 * outMetrics.density)); } });
在我的情况下,它是由align_parentBottom="true"给一个RelativeLayout的视图引起的。 删除了所有的alignParentBottom的,并将所有布局更改为垂直LinearLayouts和问题消失。
在Android 6.0上工作,遇到了同样的问题。 无论在自定义视图的根Layout设置的实际width如何, AlertDialog都将默认为在主题中设置的预定义width 。 我能够得到它设置正确调整的loading_message TextView的width 。 没有进一步调查,看起来大小的实际元素和具有根Layout环绕他们使其工作正常。 下面是一个正确设置对话框width的加载对话框的XML布局。 使用这个库的animation。
你可以在下面的代码从java设置布局的宽度和高度。
final AlertDialog alertDialog = alertDialogBuilder.create(); final WindowManager.LayoutParams WMLP = alertDialog.getWindow().getAttributes(); WMLP.gravity = Gravity.TOP; WMLP.y = mActionBarHeight; WMLP.x = getResources().getDimensionPixelSize(R.dimen.unknown_image_width); alertDialog.getWindow().setAttributes(WMLP); alertDialog.show();
你可以使用百分比的宽度。
我在这个例子中使用了Holo Theme。
将自定义对话框布局的父布局设置为RelativeLayout ,自动获取常用的宽度和高度。
早期的解决scheme之一几乎工作。 我尝试了一些不同的东西,最终为我工作。
(确保你看他的解决scheme)这是他的解决scheme。 点击这里除了:builder.getContext()。getTheme()。applyStyle(R.style.Theme_Window_NoMinWidth,true);
我改变了
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the Builder class for convenient dialog construction AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); // Get layout inflater LayoutInflater layoutInflater = getActivity().getLayoutInflater(); // Set layout by setting view that is returned from inflating the XML layout builder.setView(layoutInflater.inflate(R.layout.dialog_window_layout, null)); AlertDialog dialog = builder.create(); dialog.getContext().setTheme(R.style.Theme_Window_NoMinWidth);
最后一行是真正的不同。
@Override public void onStart() { super.onStart(); Dialog dialog = getDialog(); if (dialog != null) { dialog.getWindow().setLayout(-1, -2); dialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; Window window = getDialog().getWindow(); WindowManager.LayoutParams params = window.getAttributes(); params.dimAmount = 1.0f; window.setAttributes(params); window.setBackgroundDrawableResource(android.R.color.transparent); } }
要获得几乎覆盖整个scree的对话框:首先定义一个ScreenParameter类
public class ScreenParameters { public static int Width; public static int Height; public ScreenParameters() { LayoutParams l = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT); Width= l.width; Height = l.height; } }
然后你必须在你的getDialog.getWindow()。setLayout()方法之前调用ScreenParamater
@Override public void onResume() { super.onResume(); ScreenParameters s = new ScreenParameters(); getDialog().getWindow().setLayout(s.Width , s.Height); }