I have been trying many commands to setup the size of my DialogFragment. It only contains a color-picker, so I have removed the background and title of the dialog:
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setBackgroundDrawable(
new ColorDrawable(android.graphics.Color.TRANSPARENT));
However I also want to position the dialog where I want and it is problematic. I use:
WindowManager.LayoutParams params = getDialog().getWindow().getAttributes();
params.width = LayoutParams.WRAP_CONTENT;
params.height = LayoutParams.WRAP_CONTENT;
params.gravity = Gravity.LEFT;
getDialog().getWindow().setAttributes(params);
But one (big) obstacle remains: even though my dialog pane is invisible, it still has a certain size, and it limits the positions of my dialog. The LayoutParams.WRAP_CONTENT are here to limit the size of this pane to my color-picker, but for some reason it does not work.
Has anyone been able to do something similar?
i met a similar question that is you can't set the dialogFragment's width an height in code,after several try ,i found a solution;
here is steps to custom DialogFragment:
1.inflate custom view from xml on method
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().setCanceledOnTouchOutside(true);
View view = inflater.inflate(R.layout.XXX,
container, false);
//TODO:findViewById, etc
return view;
}
2.set your dialog's width an height in onResume(),remrember in onResume()/onStart(),seems didn't work in other method
public void onResume()
{
super.onResume();
Window window = getDialog().getWindow();
window.setLayout(width, height);
window.setGravity(Gravity.CENTER);
//TODO:
}
After some trial and error, I have found the solution.
here is the implementation of my DialogFragment class :
public class ColorDialogFragment extends SherlockDialogFragment {
public ColorDialogFragment() {
//You need to provide a default constructor
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_color_picker, container);
// R.layout.dialog_color_picker is the custom layout of my dialog
WindowManager.LayoutParams wmlp = getDialog().getWindow().getAttributes();
wmlp.gravity = Gravity.LEFT;
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_FRAME, R.style.colorPickerStyle);
// this setStyle is VERY important.
// STYLE_NO_FRAME means that I will provide my own layout and style for the whole dialog
// so for example the size of the default dialog will not get in my way
// the style extends the default one. see bellow.
}
}
R.style.colorPickerStyle corresponds to :
<style name="colorPickerStyle" parent="Theme.Sherlock.Light.Dialog">
<item name="android:backgroundDimEnabled">false</item>
<item name="android:cacheColorHint">#android:color/transparent</item>
<item name="android:windowBackground">#android:color/transparent</item>
</style>
I simply extend a default Dialog style with my needs.
Finally, you can invoke this dialog with :
private void showDialog() {
ColorDialogFragment newFragment = new ColorDialogFragment();
newFragment.show(getSupportFragmentManager(), "colorPicker");
}
For my use case, I wanted the DialogFragment to match the size of a list of items. The fragment view is a RecyclerView in a layout called fragment_sound_picker. I added a wrapper RelativeLayout around the RecyclerView.
I had already set the individual list item view's height with R.attr.listItemPreferredHeight, in a layout called item_sound_choice.
The DialogFragment obtains a LayoutParams instance from the inflated View's RecyclerView, tweaks the LayoutParams height to a multiple of the list length, and applies the modified LayoutParams to the inflated parent View.
The result is that the DialogFragment perfectly wraps the short list of choices. It includes the window title and Cancel/OK buttons.
Here's the setup in the DialogFragment:
// SoundPicker.java
// extends DialogFragment
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getActivity().getString(R.string.txt_sound_picker_dialog_title));
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
View view = layoutInflater.inflate(R.layout.fragment_sound_picker, null);
RecyclerView rv = (RecyclerView) view.findViewById(R.id.rv_sound_list);
rv.setLayoutManager(new LinearLayoutManager(getActivity()));
SoundPickerAdapter soundPickerAdapter = new SoundPickerAdapter(getActivity().getApplicationContext(), this, selectedSound);
List<SoundItem> items = getArguments().getParcelableArrayList(SOUND_ITEMS);
soundPickerAdapter.setSoundItems(items);
soundPickerAdapter.setRecyclerView(rv);
rv.setAdapter(soundPickerAdapter);
// Here's the LayoutParams setup
ViewGroup.LayoutParams layoutParams = rv.getLayoutParams();
layoutParams.width = RelativeLayout.LayoutParams.MATCH_PARENT;
layoutParams.height = getListItemHeight() * (items.size() + 1);
view.setLayoutParams(layoutParams);
builder.setView(view);
builder.setCancelable(true);
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
// ...
});
builder.setPositiveButton(R.string.txt_ok, new DialogInterface.OnClickListener() {
// ...
});
return builder.create();
}
#Override
public void onResume() {
Window window = getDialog().getWindow();
window.setLayout(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
super.onResume();
}
private int getListItemHeight() {
TypedValue typedValue = new TypedValue();
getActivity().getTheme().resolveAttribute(R.attr.listPreferredItemHeight, typedValue, true);
DisplayMetrics metrics = new android.util.DisplayMetrics(); getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
return (int) typedValue.getDimension(metrics);
}
Here is fragment_sound_picker:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_sound_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
use this code for resize of Dialog Fragment android
public void onResume() {
super.onResume();
Window window = getDialog().getWindow();
window.setLayout(250, 100);
window.setGravity(Gravity.RIGHT);
}
Related
Good day, apologies if this seems to be a duplicate of a question that's been asked before.
I have and Android App and I am displaying a Dialog Fragment. The problem I have is that the width of the Dialog Fragment is ignored when the base activity is showing it. Here's the code in my onCreateDialog function:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Dialog dialog = new Dialog(getActivity());
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
LayoutInflater layoutInflater = (LayoutInflater) getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout2 = layoutInflater.inflate(R.layout.fragment_item_dialog, null);
dialog.setContentView(layout2);
setStyle(DialogFragment.STYLE_NORMAL, R.style.MyDialog);
Window window = dialog.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
window.setGravity(Gravity.TOP|Gravity.LEFT);
WindowManager.LayoutParams params = window.getAttributes();
params.x = 20;
params.y = 470;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.copyFrom(window.getAttributes());
window.setAttributes(params);
// -- more code here
}
and here is my xml file fragment_item_dialog
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="400dp"
android:layout_height="wrap_content" >
<!--- code here ---!>
</RelativeLayout>
The height is followed properly, but Android keeps on setting the width to match parent even though I told it to wrap content. The components inside my dialog Fragment does not exceed 400dp and I have no clue why Android is forcing my layout to match parent.
Does anyone know how to work around this? Any help is very much appreciated. Thanks.
Made it work, use the same code on onStart()
#Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (getDialog() == null)
return;
int width = 1100;
int height = getResources().getDisplayMetrics().heightPixels;
getDialog().getWindow().setLayout(width,
WindowManager.LayoutParams.WRAP_CONTENT);
}
I have a DialogFragment where I create the alertDialog in the onCreate():
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
if (alertDialog == null) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
alertDialog = builder.create();
alertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
alertDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
alertDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
alertDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
}
alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
alertDialog.setView(getDialogLayout(),0,0,0,0);
return alertDialog;
}
Then I set the width (dialogWidth) of alertDialog in the onStart():
#Override
public void onStart() {
super.onStart();
WindowManager.LayoutParams lp = alertDialog.getWindow().getAttributes();
lp.width = dialogWidth;
lp.x = Constants.iX_PositionDialog;
lp.y = Constants.iY_PositionDialog;
alertDialog.getWindow().setAttributes(lp);
}
In my case i set the width of the dialog to 648 but the canvas/window of my surfaceView is just 590, why?
I need the width i set.
Set the layout after show() method of alertDialog.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(layout);
builder.setTitle("Title");
alertDialog = builder.create();
alertDialog.show();
alertDialog.getWindow().setLayout(648, 400); //Controlling width and height.
NOTE: Setting the layout after show() is the key point.
For more - how-to-control-the-width-and-height-of-default-alert-dialog-in-android.
To set the width and height of your alert dialouge for siffrent screen use:
int dialogWidth = getActivity().getResources().getDisplayMetrics().widthPixels-120; // screen width - whatever the width you want to set.
int dialogHeight = getActivity().getResources().getDisplayMetrics().heightPixels -140; //screen height - whatever the width you want to set.
getDialog().setCanceledOnTouchOutside(false);
Window window = getDialog().getWindow();
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.gravity = Gravity.CENTER;
lp.height = dialogHeight;
lp.width = dialogWidth;
window.setAttributes(lp);
its a best practice as in andorid there are many devices and of many resolution,so we have to do everythign according to diffrent screen.so that it will be feasible with all types of screens.
I found the solution for my self.
So the alertDialog View is packed in an few FrameLayouts.
the Padding of some of these are not 0.
According of this helping code here :[AlertDialog with custom view: Resize to wrap the view's content
I make it with the following methode which i call in the onStart methode:
protected void forceWrapContent(View v) {
// Start with the provided view
View current = v;
// Travel up the tree until fail, modifying the LayoutParams
do {
// Get the parent
ViewParent parent = current.getParent();
// Check if the parent exists
if (parent != null) {
// Get the view
try {
current = (View) parent;
} catch (ClassCastException e) {
// This will happen when at the top view, it cannot be cast to a View
break;
}
// Modify the layout
current.getLayoutParams().width = dialogWidth;
current.setPadding(0, 0, 0, 0);
}
} while (current.getParent() != null);
// Request a layout to be re-done
current.requestLayout();
}
Thanks!
This question already has answers here:
Position of DialogFragment in Android
(8 answers)
Closed 9 years ago.
I'm trying to locate my dialog in a specific location on screen.
Here is my dialog implementation :
public class DayDialog extends android.support.v4.app.DialogFragment {
public static DayDialog newInstance() {
DayDialog f = new DayDialog();
f.setCancelable(true);
f.setStyle(STYLE_NO_TITLE, 0);
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.dialog_calendar_day, container);
WindowManager.LayoutParams params = getDialog().getWindow()
.getAttributes();
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;//b.getInt("x");
params.y = 0;//b.getInt("y");
getDialog().getWindow().setAttributes(params);
return layout;
}
here is how my dialog shown! how can I locate it (0,0) ? it's like there is a frame or something around it!
screenshot
There is fact a frame around it, that is defined in styles.xml, more specific it's the this 9-patch. The way i see it you have two options:
Start playing around with negative top/left margin params until you align it exactly where you want it (watch out to use dpi values).
Apply the DialogFragment.STYLE_NO_FRAME like so:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_FRAME, 0);
}
How do I show a progress dialog on Android without blocking clicks on the other UI elements on the screen (like Ads) ?
public void addProgressBar(Activity activity){
final ViewGroup rootFrameLayout = (ViewGroup) activity.getWindow().peekDecorView();
final ViewGroup modal = new RelativeLayout(activity);
ProgressBar progressBar = new ProgressBar(activity);
LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
modal.addView(progressBar, layoutParams);
rootFrameLayout.addView(modal, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
rootFrameLayout.invalidate();
}
You have to use ProgressBar view, and create a separate overlay for the progress bar.
The most transparent way would be to create an abstract Activity and override the setContentView() method (both with id, and View, shown only with id). Than you can inherit your Activities from this one, and use it as a normal Activity with the added benefit of showProgress and hideProgress methods.
private HashMap<View, ProgressBar> progressBars = new HashMap<View, ProgressBar>();
private RelativeLayout overlay;
public void setContentView(int id) {
FrameLayout combinedView = new FrameLayout();
combinedView.setLayoutParams(new ViewGroup.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
View background = getLayoutInflater().inflate(id, null);
background.setLayoutParams(new ViewGroup.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
combinedView.addView(background);
overlay = new RelativeLayout();
overlay.setLayoutParams(new ViewGroup.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
combinedView.addView(overlay);
super.setContentView(combinedView);
}
public void showProgress(View view) {
ProgressBar progressBar = progressBars.get(view);
if (progressBar == null) {
progressBar = new ProgressBar();
progressBars.put(view, progressBar);
progressBar.setLayoutParams(new ViewGroup.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
overlay.addView(progressBar);
}
int[] position = view.getLocationOnScreen();
int width = view.getWidth();
int height = view.getHeight();
int progressWidth = progressBar.getWidth();
int progressHeight =progressBar.getHeight();
progressBar.setMargins(position[0] + width / 2 - progressWidth/2,
position[1] + height / 2 - progressHeight/2,0,0);
progressBar.setVisibility(View.VISIBLE);
}
public void hideProgress(View view) {
ProgressBar progressBar = progressBars.get(view);
if (progressBar != null) {
progressBar.setVisibility(View.INVISIBLE);
}
}
You can create a completely transparent Linear or any other kind of layout with a ProgressBar in center and add this layout in a FrameLayout which contain all your other controls. Now when you want to show the progress bar make this layout visible and make invisible when you do not want it to show.
bankings method I felt was the best and the simplest to implement. Just for the convenience of anybody wanting to use it, rather make the method return ProgressBar and when you want to remove this progress bar, you can use this return value to just set its visibility to gone as shown for example
progressBar.setVisibility(View.GONE);
Hope it adds value to the above answers.
When a dialog appears, it adds a layer to underlaying view blocking all events on it.
To achieve what you are looking for, you can create a view similar to dialog view and show it instead of dialog. For dialogs and transparent background activity, your target won't be achieved.
#banking's method is sweet and short, I have modified it a little to use with layout file instead of creating it with Java code:
progress_spinner.xml: (in layout folder)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center">
<ProgressBar
android:id="#+id/ProgressBar"
style="?android:attr/progressBarStyleInverse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
</RelativeLayout>
Java:
ProgressBar progressBar=null;
public void addProgressBar(Activity activity) {
ViewGroup rootFrameLayout = (ViewGroup) activity.getWindow().peekDecorView();
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View progressModal = inflater.inflate(R.layout.progress_spinner, rootFrameLayout, false);
rootFrameLayout.addView(progressModal, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
rootFrameLayout.invalidate();
progressBar = (ProgressBar) progressModal.findViewById(R.id.ProgressBar);
}
public void hideProgressBar() {
if (progressBar != null)
progressBar.setVisibility(View.INVISIBLE);
}
public void showProgressBar() {
if (progressBar != null)
progressBar.setVisibility(View.VISIBLE);
}
I am trying to create a custom DialogFragment, that extends over the whole width of my screen (or rather, parent fragment). Although I can make the borders of the DialogFragment transparent, there still is a padding on the right and left that I cannot get rid of.
This is my Fragment:
public static class LoaderDialog extends DialogFragment {
static LoaderDialog newInstance() {
LoaderDialog f = new LoaderDialog();
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.loader_f, container, false);
WindowManager.LayoutParams p = getDialog().getWindow().getAttributes();
p.y = getSupportActionBar().getHeight();
getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
getDialog().getWindow().setGravity(Gravity.TOP);
getDialog().getWindow().setAttributes(p);
return view;
}
}
This is a picture, how it looks like:
As you can see, the DialogFragment (the red thing) has some margins on the side. I want those to be gone. Any idea how to do this (in java, if possible)?
You can use:
WindowManager.LayoutParams wmlp = getDialog().getWindow().getAttributes();
wmlp.gravity = Gravity.FILL_HORIZONTAL;
Full example:
public class TextEditor extends DialogFragment {
public TextEditor () {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_text_editor, container);
WindowManager.LayoutParams wmlp = getDialog().getWindow().getAttributes();
wmlp.gravity = Gravity.FILL_HORIZONTAL;
return view;
}
}
try this:
p.horizontalMargin = 0;
use this style for DialogFragment
<item name="android:windowNoTitle">true</item>
<item name="android:padding">0dp</item>
or use this code in onCreateView method of DialogFragment
Display display = getActivity().getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, **220**, getResources().getDisplayMetrics());
getDialog().getWindow().setLayout(width,px);
ps. 220 is DialogFragment height, change it as u wish
Create a style element in your style.xml file. Copy the code below to your style.xml file
<style name="CustomDialog" parent="#android:style/Theme.Holo.Light" >
<item name="android:windowBackground">#null</item>
<item name="android:windowIsFloating">true</item>
Then in the createDialog method of your DialogFragment class,
dialog = new Dialog(getActivity(), R.style.CustomDialog);
This is working for me and hope this will help you too
Try to use LayoutParams.MATCH_PARENT instead. Fill_parent is drepecated. Moreover if you have set a padding for your view that is normal that is not fill its parent's view.