DialogFragment在Android中的位置

我有一个DialogFragment来显示一个像Popup屏幕的View 。 该窗口始终显示在屏幕的中间。 有没有办法设置DialogFragment窗口的位置? 我查看了源代码,但是还找不到任何东西。

尝试这样的事情:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { getDialog().getWindow().setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP); WindowManager.LayoutParams p = getDialog().getWindow().getAttributes(); p.width = ViewGroup.LayoutParams.MATCH_PARENT; p.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE; px = 200; ... getDialog().getWindow().setAttributes(p); ... 

或者getDialog().getWindow()其他方法。

请务必在调用set-content之后设置位置。

对,我用这个在墙上撞了一两个小时,终于得到了我想要的DialogFragment

我在这里build立在Steelight的答案上 。 这是我发现的最简单,最可靠的方法。

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle b) { Window window = getDialog().getWindow(); // set "origin" to top left corner, so to speak window.setGravity(Gravity.TOP|Gravity.LEFT); // after that, setting values for x and y works "naturally" WindowManager.LayoutParams params = window.getAttributes(); params.x = 300; params.y = 100; window.setAttributes(params); Log.d(TAG, String.format("Positioning DialogFragment to: x %d; y %d", params.x, params.y)); } 

请注意, params.widthparams.softInputMode (在Steelight的答案中使用)与此无关。


下面是一个更完整的例子。 我真正需要的是在“源”或“父”视图旁边alignment“确认框”DialogFragment,在我的情况下是一个ImageButton。

我select使用DialogFragment,而不是任何自定义片段,因为它提供了免费的“对话”function(当用户点击它时closures对话框等)。

示例ConfirmBox
示例ConfirmBox上方的“源”ImageButton(垃圾桶)

 /** * A custom DialogFragment that is positioned above given "source" component. * * @author Jonik, https://stackoverflow.com/a/20419231/56285 */ public class ConfirmBox extends DialogFragment { private View source; public ConfirmBox() { } public ConfirmBox(View source) { this.source = source; } public static ConfirmBox newInstance(View source) { return new ConfirmBox(source); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setStyle(STYLE_NO_FRAME, R.style.Dialog); } @Override public void onStart() { super.onStart(); // Less dimmed background; see https://stackoverflow.com/q/13822842/56285 Window window = getDialog().getWindow(); WindowManager.LayoutParams params = window.getAttributes(); params.dimAmount = 0.2f; // dim only a little bit window.setAttributes(params); // Transparent background; see https://stackoverflow.com/q/15007272/56285 // (Needed to make dialog's alpha shadow look good) window.setBackgroundDrawableResource(android.R.color.transparent); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Put your dialog layout in R.layout.view_confirm_box View view = inflater.inflate(R.layout.view_confirm_box, container, false); // Initialise what you need; set eg button texts and listeners, etc. // ... setDialogPosition(); return view; } /** * Try to position this dialog next to "source" view */ private void setDialogPosition() { if (source == null) { return; // Leave the dialog in default position } // Find out location of source component on screen // see https://stackoverflow.com/a/6798093/56285 int[] location = new int[2]; source.getLocationOnScreen(location); int sourceX = location[0]; int sourceY = location[1]; Window window = getDialog().getWindow(); // set "origin" to top left corner window.setGravity(Gravity.TOP|Gravity.LEFT); WindowManager.LayoutParams params = window.getAttributes(); // Just an example; edit to suit your needs. params.x = sourceX - dpToPx(110); // about half of confirm button size left of source view params.y = sourceY - dpToPx(80); // above source view window.setAttributes(params); } public int dpToPx(float valueInDp) { DisplayMetrics metrics = getActivity().getResources().getDisplayMetrics(); return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, metrics); } } 

根据需要通过添加构造函数参数或setter来使上述更通用是很容易的。 (我的最后ConfirmBox有一个风格的button(在一些边框内),其文本和View.OnClickListener可以在代码中定制。)

getDialog().getWindow()不能用于DialogFragment因为如果主机活动不可见, getWindow()将返回null,如果您正在编写基于片段的应用程序,则返回null。 当您尝试getAttributes()时,您将得到一个NullPointerException

我build议Mobistry的答案。 如果你已经有了一个DialogFragment类,切换并不难。 只需将onCreateDialog方法replace为构造并返回PopupWindow。 那么你应该能够重用你提供给AlertDialog.builder.setView()的视图,并调用(PopupWindow object).showAtLocation()

我为此使用PopupWindow类,因为您可以指定视图的位置和大小。

您需要重写DialogFragment中的onResume()方法,如下所示:

 @Override public void onResume() { final Window dialogWindow = getDialog().getWindow(); WindowManager.LayoutParams lp = dialogWindow.getAttributes(); lp.x = 100; // set your X position here lp.y = 200; // set your Y position here dialogWindow.setAttributes(lp); super.onResume(); }