DialogFragment Position in Android

I have a DialogFragment to show the View as a popup. A window always appears in the middle of the screen. Is there a way to set the position of the DialogFragment window? I looked at the source code but could not find anything.

+51
android android-layout android-fragments android-dialogfragment
Mar 14 2018-12-12T00:
source share
7 answers

Try something like this:

 @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); ... 

or other methods for getDialog().getWindow() .

be sure to set the position after calling set-content.

+82
Apr 24 2018-12-12T00:
source share

That's right, I hit my head on the wall for an hour or two with this, before finally getting the DialogFragment as I wanted.

I will describe Steelight's answer here. This is the easiest and most reliable approach I have found.

 @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)); } 

Note that params.width and params.softInputMode (used in Steelight's answer) are irrelevant for this.




Below is a more complete example. What I really need is to align the โ€œconfirmโ€ checkbox of the dialog box next to the โ€œsourceโ€ or โ€œparentโ€ view, in my case ImageButton.

I decided to use DialogFragment instead of any user fragment, because it gives you "dialog" functions for free (close the dialog when the user clicks outside, etc.).

Example ConfirmBox
ConfirmBox example above its "original" ImageButton (trashcan)

 /** * 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 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); } } 

It is very simple to make the above more general use by adding constructor or setter options as needed. (My last ConfirmBox has a stylized button (inside some borders, etc.) whose text and View.OnClickListener can be configured in the code.)

+73
Dec 06 '13 at 8:22
source share

getDialog().getWindow() will not work for DialogFragment , since getWindow() will return null if host activity is not visible, which does not mean that you are writing an application based on fragments. You will get a NullPointerException when you try getAttributes() .

I recommend the answer to Mobistry. If you already have a DialogFragment class, it's not that hard to switch. Just replace the onCreateDialog method with the one that creates and returns PopupWindow. Then you should be able to reuse the View you supply to AlertDialog.builder.setView() and call (PopupWindow object).showAtLocation() .

+4
Oct. 27
source share

I use the PopupWindow class for this purpose because you can specify the location and size of the view.

+3
Aug 2 2018-12-12T00:
source share

You need to override the onResume () method in your DialogFragment, as shown below:

 @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(); } 
+3
Jul 16 '16 at 6:36
source share
 @Override public Dialog onCreateDialog(Bundle savedInstanceState) { Dialog dialog = new Dialog(mActivity, R.style.BottomDialog); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); // dialog.setContentView(R.layout.layout_video_live); dialog.setCanceledOnTouchOutside(true); Window window = dialog.getWindow(); assert window != null; WindowManager.LayoutParams lp = window.getAttributes(); lp.gravity = Gravity.BOTTOM; //psotion lp.width = WindowManager.LayoutParams.MATCH_PARENT; // fuill screen lp.height = 280; window.setAttributes(lp); return dialog; } 
+1
26 Oct '18 at 8:53
source share

I am using AppCompatDialogFragment from android.support.v7.app.AppCompatDialogFragment and I want to align the dialog fragment to the bottom of the screen and also remove all borders, especially I had to set the width of the content according to the parent.

So, I wanted from this (the yellow background comes from the rootLayout fragment of the dialog):

src_img_1

Take this:

src_img_2

None of the above solutions worked. So, I managed to do this:

 fun AppCompatDialogFragment.alignToBottom() { dialog.window.apply { setGravity(Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL) decorView.apply { // Get screen width val displayMetrics = DisplayMetrics().apply { windowManager.defaultDisplay.getMetrics(this) } setBackgroundColor(Color.WHITE) // I don't know why it is required, without it background of rootView is ignored (is transparent even if set in xml/runtime) minimumWidth = displayMetrics.widthPixels setPadding(0, 0, 0, 0) layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT) invalidate() } } } 
0
Jan 24 '19 at 13:02
source share



All Articles