How to set dialog window background to transparent, without affecting its margin - android

Currently, I have the following dialog, which I will perform expand/ collapse animation on its items.
This dialog is created via the following code
import android.support.v7.app.AlertDialog;
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
final AlertDialog dialog = builder.setView(view).create();
final ViewTreeObserver vto = view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
ViewTreeObserver obs = view.getViewTreeObserver();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
obs.removeOnGlobalLayoutListener(this);
} else {
obs.removeGlobalOnLayoutListener(this);
}
// http://stackoverflow.com/questions/19326142/why-listview-expand-collapse-animation-appears-much-slower-in-dialogfragment-tha
int width = dialog.getWindow().getDecorView().getWidth();
int height = dialog.getWindow().getDecorView().getHeight();
dialog.getWindow().setLayout(width, height);
}
});
However, when animation being performed, here's the side effect.
Note, the unwanted extra white region at the dialog after animation, is not caused by our custom view. It is the system window white background of the dialog itself.
I tend to make the system window background of the dialog, to become transparent.
final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
final AlertDialog dialog = builder.setView(view).create();
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
Although the unwanted white background is no longer seen, the original margin of the dialog is gone too. (The dialog width is now full screen width)
How can I make it transparent, without affecting its margin?

There's a pretty easy way to do that:
You need to "modify" the Drawable that is being used as a background of the Dialog. Those sort of Dialogs use an InsetDrawable as a background.
API >= 23
Only SDK API 23+ allows you to get the source Drawable wrapped by the InsetDrawable (getDrawable() method). With this, you can do whatever you want - e.g. change color to something completely different (like RED or something). If you use this approach remember that the wrapped Drawable is a GradientDrawable and not a ColorDrawable!
API < 23
For lower APIs your ("elegant") options are very limited.
Fortunately you don't need to change the color to some crazy value, you just need to change it to TRANSPARENT. For this you can use setAlpha(...) method on InsetDrawable.
InsetDrawable background =
(InsetDrawable) dialog.getWindow().getDecorView().getBackground();
background.setAlpha(0);
EDIT (as a result of Cheok Yan Cheng's comments):
or you can actually skip casting to InsetDrawable and get the same result. Just remember that doing so will cause the alpha to be changed on the InsetDrawable itself and not on the Drawable that is wrapped by the InsetDrawable.

Try to below Theme:
<style name="TransaparantDialog">
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowFrame">#null</item>
<item name="android:windowTitleStyle">#null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowAnimationStyle">#android:style/Animation.Dialog</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:background">#android:color/transparent</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
</style>
Try below code to apply Theme to AlertDialog.Builder:
final AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(activity, R.style.TransaparantDialog));
...
dialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
I hope help you !

The background image abc_popup_background_mtrl_mult which is part of the compat library contains already a margin in the picture information.
This is why the margin goes away when you remove the background image. I strongly recommend not to use the ViewTreeObserver, it will been called multiple times and can cause performance issues. Better work with the screen size:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Your problem is properly in the layout try to check the views with the Hierarchy viewer.

just add this line after show dialog. I would prefer using Dialog instedof using AlertDialog
dialog.getWindow().setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

Let's start with Google recommendation which says to use DialogFragment instead of a simple Dialog.
#rekire is right that margins set by drawable, going forward it is set by either 9 patch or programmatically depending on theme.
So you either can set your padding to your content view or create dialog using DialogFragment here is an example which changes height of dialog based on it's content, and note you don't need to use tree observer which is as mentioned before may cause performance issue.
So the example
dialog_confirm.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp">
<LinearLayout android:id="#+id/container"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:orientation="vertical"
android:animateLayoutChanges="true"
android:padding="15dp">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="10dp"
android:text="A label text"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="10dp"
android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque mauris mi, dictum a lectus ut, facilisis"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Remove Me"/>
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Remove Me"/>
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Remove Me"/>
<!-- as much content as you need -->
</LinearLayout>
</ScrollView>
Note: I wrapped everything into scroll view and set padding you can skip it if you want.
ConfirmDialog.java
//here goes package name and imports
/**
* Created by Vilen - virtoos.com;
* fragment dialog example
*/
public class ConfirmDialog extends DialogFragment implements View.OnClickListener {
private Button button1;
private Button button2;
private Button button3;
private LinearLayout containerLayout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, 0);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.dialog_confirm, container, false);
containerLayout = (LinearLayout)v.findViewById(R.id.container);
button1 = (Button)v.findViewById(R.id.button1);
button2 = (Button)v.findViewById(R.id.button2);
button3 = (Button)v.findViewById(R.id.button3);
button1.setOnClickListener(this);
button2.setOnClickListener(this);
button3.setOnClickListener(this);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// make background transparent if you want
//getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return super.onCreateDialog(savedInstanceState);
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.button1:
containerLayout.removeView(button1);
break;
case R.id.button2:
containerLayout.removeView(button2);
break;
case R.id.button3:
containerLayout.removeView(button3);
break;
}
}
}
and finally you can show your dialog with this piece of code
ConfirmDialog confirmDialog = new ConfirmDialog();
confirmDialog.show(getSupportFragmentManager(), "dialog");
I will not go into details why Fragment dialog is better but one thing is clear that you can encapsulate logic for it and have separate class.
Hope this solves your issue.

What should be there is what you didn't show, I'm not sure it is something you didn't know or it is already there so you don't think it is necessary to show.
Set theme to Dialog, that puts entire activity as one Dialog. I don't think you did it, otherwise AlertDialog would not be there.
I'm a bit lost your description, but there is that little <shape/> XML that is much more powerful then a 9-patch, and use RelativeLayout will help.

Related

Setting custom font to Dialog

We are trying to set the title of a dialog to have a custom font so we tried doing a theme with the following:
<style name="DialogTheme" parent="Theme.AppCompat.Dialog.Alert">
<item name="android:windowTitleStyle">#style/Dialog.Title</item>
</style>
<style name="Dialog.Title" parent="RtlOverlay.DialogWindowTitle.AppCompat">
<item name="android:textAppearance">#style/Dialog.TextAppearance.Title</item>
</style>
<style name="Dialog.TextAppearance.Title" parent="TextAppearance.AppCompat.Title">
<item name="fontFamily">#font/custom_font</item>
</style>
And we are creating the dialog builder like this:
AlertDialog.Builder(ContextThemeWrapper(context, R.style.DialogTheme), R.style.DialogTheme)
The style and text appearance are completely ignored. For other styles, it seems to be working.
We managed to make it work by copying the layout used by AppCompat and adding it as a custom title:
<?xml version="1.0" encoding="utf-8"?>
<!-- modified from AppCompat's abc_alert_dialog_title_material.xml -->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical|start|left"
android:paddingLeft="?attr/dialogPreferredPadding"
android:paddingRight="?attr/dialogPreferredPadding"
android:paddingTop="#dimen/abc_dialog_padding_top_material">
<TextView
android:id="#+id/alertTitle"
style="#style/Dialog.Title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textAlignment="viewStart"
tools:text="Some title" />
</FrameLayout>
Based on this: abc_alert_dialog_title_material.xml
Instead of using DialogTitle here we are using TextView. What DialogTitle is overloading onMeasure with the following:
final Layout layout = getLayout();
if (layout != null) {
final int lineCount = layout.getLineCount();
if (lineCount > 0) {
final int ellipsisCount = layout.getEllipsisCount(lineCount - 1);
if (ellipsisCount > 0) {
setSingleLine(false);
setMaxLines(2);
final TypedArray a = getContext().obtainStyledAttributes(null,
R.styleable.TextAppearance,
android.R.attr.textAppearanceMedium,
android.R.style.TextAppearance_Medium);
final int textSize = a.getDimensionPixelSize(
R.styleable.TextAppearance_android_textSize, 0);
if (textSize != 0) {
// textSize is already expressed in pixels
setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
}
a.recycle();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
We think it's related with it setting the text size, but we are not sure. We have a working hack (with the copied layout). However, we would prefer to know how we can make it work with xml styles and themes instead of having to change the default behaviour.
From my answer to another question I just posted recently, this is how I was able to programmatically set the font of all attributes of an AlertDialog. Hope it works for you.
Typeface semibold = ResourcesCompat.getFont(this, R.font.product_bold);
Typeface regular = ResourcesCompat.getFont(this, R.font.product_regular);
AlertDialog myDialog = new AlertDialog.Builder(this).setTitle("Your title")
.setMessage("Your message.")
.setPositiveButton("Your button", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//your code
}
}).show();
int titleText = getResources().getIdentifier("alertTitle", "id", "android");
((TextView) myDialog.getWindow().findViewById(titleText)).setTypeface(semibold);
TextView dialogMessage = myDialog.getWindow().findViewById(android.R.id.message);
Button dialogButton = myDialog.getWindow().findViewById(android.R.id.button1);
dialogMessage.setTypeface(regular);
dialogButton.setTypeface(semibold);
Confirmed working on Android 9.0, can't claim for it to work on older APIs.
Another method of programmatically setting the title with a TextView, this is how I used to do it:
TextView alertTitle = findViewById(R.id.alertTextTemp);
if (alertTitle.getParent() != null) {
((ViewGroup) alertTitle.getParent()).removeView(alertTitle);
}
alertTitle.setText("Warning");
alertTitle.setVisibility(View.VISIBLE);
alertTitle.setTypeface(semibold);
Then when you create your dialog, you set a custom title with:
new AlertDialog.Builder(MainActivity.this).setCustomTitle(alertTitle)...
alertTitle being a TextView in your activity_main.xml file:
<TextView
android:id="#+id/alertTextTemp"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22sp"
android:paddingLeft="23dp"
android:paddingTop="22dp"
android:textColor="#000000" />
Those attributes on the TextView I had to fine tune to get it as close to the default title margins and size as possible, you might want to verify it works for you.

Show entire bottom sheet with EditText above Keyboard

I'm implementing a UI where a bottom sheet will appear above the keyboard with an EditText for the user to enter a value. The problem is the View is being partially overlapped by the keyboard, covering up the bottom of the bottom sheet.
Here is the Bottom Sheet and no keyboard.
Here is the Bottom Sheet with the keyboard showing.
What's the best method to ensure the entire Bottom Sheet is shown?
Thanks.
Just reposting #jblejder from this question Keyboard hides BottomSheetDialogFragment since it worked for me, to make it easier for others to find:
The most convenient way that I found to change this is by creating style:
<style name="DialogStyle" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowSoftInputMode">adjustResize</item>
</style>
And set this in onCreate method of your BottomSheetDialogFragment:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(DialogFragment.STYLE_NORMAL, R.style.DialogStyle)
}
This is how it looks on my device:
==== UPDATE ====
As already mentioned in the Comments a few times, you might also need to set the state of the BottomSheetDialog to STATE_EXPANDED like in Nordknight's answer below
dialog = new BottomSheetDialog(getContext(), R.style.BottomSheetDialog);
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
BottomSheetDialog d = (BottomSheetDialog) dialog;
FrameLayout bottomSheet = d.findViewById(R.id.design_bottom_sheet);
BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
},0);
}
});
This might be a redundant answer. Although just pointing out the issue.
If you're using BottomSheetDialogFragment, the only way is to enable the attribute android:windowIsFloating to true. This will enable the whole window to be on top of whatever is trying to take the space behind it.
<style name="BottomSheetDialogThemeNoFloating" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowSoftInputMode">adjustResize|stateVisible</item>
</style>
Then in your onCreate() of your dialog, set this style.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// set the window no floating style
setStyle(DialogFragment.STYLE_NORMAL, R.style.AppRoundedBottomSheetDialogThemeNoFloating)
}
This is handy for those who frequently use bottom sheets and may want to deal with EditText and soft keyboard overlapping each other.
Note: The class KeyboardUtil by mikepenz has an issue in which on certain phones, the content view with input field is automatically pushed above keyboard despite giving bottom padding to the whole content view supplied.
dialog = new BottomSheetDialog(getContext(), R.style.BottomSheetDialog);
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
BottomSheetDialog d = (BottomSheetDialog) dialog;
FrameLayout bottomSheet = d.findViewById(R.id.design_bottom_sheet);
BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
},0);
}
});
This code works fine at Fragment's onCreateView method (thanks for ADM)
Some answers seem to do the trick better than others but will need modification when using the new material design components instead of the older support libraries while also using kotlin
Hope this will help someone.
BottomSheetDialog(this, R.style.DialogStyle).apply {
setContentView(layoutInflater.inflate(R.layout.bottom_sheet, null))
window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
findViewById<EditText>(R.id.time_et)?.requestFocus()
show()
}
layout/bottom_sheet.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:padding="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="5"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Time"
android:textColor="#000000"
android:textSize="24sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<EditText
android:id="#+id/time_et"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="numberSigned"
android:minWidth="50dp"
android:text="15" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:text="min" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="#000"
android:text="Save"
android:textColor="#fff" />
</LinearLayout>
</ScrollView>
styes.xml (Split for v-21 for using statusBarColor)
<style name="DialogStyle" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowSoftInputMode">adjustResize</item>
</style>
A BottomSheetDialog can be helpful for this. it will open with Softkeyboard open with focus on edit text.But user can still close the Softkeyboard and Dialog will be reset to Bottom. Again focusing will make dialog appear at top of Softkeyboard.
public void showDialog() {
final BottomSheetDialog dialog=new BottomSheetDialog(this);
dialog.setContentView(R.layout.item_dialog);
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
dialog.show();
}
You can make the BottomSheetDialog expanded over keyboard . But for this you need to call it after SoftKeyboard Open. the Expand code is .
BottomSheetDialog d = (BottomSheetDialog) dialog;
FrameLayout bottomSheet = (FrameLayout) d.findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
I have tested it on DialogInterface.OnShowListener() but its not working . Tested with it 1 second delay its working . But Delay is not the solution . You need to figure out the on which action you should expand the dialog.
final BottomSheetDialog dialog=new BottomSheetDialog(this);
dialog.setContentView(R.layout.item_dialog);
dialog.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE|
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
FrameLayout bottomSheet = (FrameLayout) dialog.findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
}
},2000);
dialog.show();
An updated answer for those using Material Components theme, and also an improved answer to remove the need to add anything into each dialog's onCreate().
In your main AppTheme style, you can add the attribute bottomSheetDialogTheme to apply the style to all of your BottomSheetDialogFragments:
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
<item name="colorPrimary">#color/primary</item>
<item name="colorPrimaryDark">#color/primary_dark</item>
<item name="colorAccent">#color/accent</item>
<item name="bottomSheetDialogTheme">#style/BottomSheetDialogStyle</item>
</style>
So with the above, no need to add anything to your BottomSheetDialogFragment code.
And then, as previous answers, your Dialog style, noting to also match the style to the same Material Components library (or you'll get some weird looking buttons, edittexts etc):
<style name="BottomSheetDialogStyle" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowSoftInputMode">adjustResize</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="colorPrimary">#color/primary</item>
<item name="colorPrimaryDark">#color/primary_dark</item>
<item name="colorAccent">#color/accent</item>
</style>
Note that I am adding my app theme colors back in here; as you can't have multiple inheritance in Android styles, you may want these colors defining here so any buttons and accents align with the rest of your app.
private fun enterMobileNumberPopUp() {
val dialog = BottomSheetDialog(this,R.style.DialogStyle)
val view = layoutInflater.inflate(R.layout.layout_otp, null)
dialog.setContentView(view)
dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
dialog.show()}
THIS IS THE MOST EASY WAY AND BEST WAY TO HANDLE BOTTOM SHEET DIALOG
YOU CAN CALL THIS IN METHOD
<style name="DialogStyle" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowSoftInputMode">adjustResize</item>
Style reference
This one working
BottomSheetDialog dialog = new BottomSheetDialog(this, R.style.DialogStyle);
View sheetView = getLayoutInflater().inflate(R.layout.dialog_remark, null);
Objects.requireNonNull(dialog.getWindow())
.setSoftInputMode(SOFT_INPUT_STATE_VISIBLE);
dialog.setContentView(sheetView);
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
BottomSheetDialog d = (BottomSheetDialog) dialog;
View bottomSheetInternal = d.findViewById(com.google.android.material.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheetInternal).setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
dialog.show();
add this style to your styles.xml
<style name="DialogStyle" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowSoftInputMode">adjustPan</item>
</style>
add your layout like this
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="#+id/scrollview"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="8dp"
android:fontFamily="#font/montserratmedium"
android:text="Add Remarks"
android:textColor="#android:color/black"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="24dp"
android:fontFamily="#font/montserratmedium"
android:text="Branch"
android:textColor="#8B8B8B"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:fontFamily="#font/montserratmedium"
android:text="BLR-CO-SINDHUBHAVAN-384"
android:textColor="#android:color/black"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="24dp"
android:fontFamily="#font/montserratmedium"
android:text="Enter Remarks"
android:textColor="#8B8B8B"
android:textSize="18sp" />
<EditText
android:id="#+id/input_remark"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="8dp"
android:background="#drawable/remark_inputbg"
android:gravity="start"
android:inputType="textMultiLine"
android:lines="5" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_weight="1"
android:background="#drawable/reset_bg"
android:padding="8dp"
android:text="CANCEL" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_weight="1"
android:background="#4F4DBB"
android:padding="8dp"
android:text="CANCEL"
android:textColor="#android:color/white" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</ScrollView>
bottomSheetDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
It will work for sure.
Just write the following programmatically
override fun setupDialog(dialog: Dialog, style: Int) {
super.setupDialog(dialog, style)
dialog.window?.setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE or
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
);
}
Kotlin, +viewBinding, +by using the accepted answer's dialog style
val bottomSheet = BottomSheetDialog(this, R.style.BottomSheetDialogStyle)
val binding = [YourSheetBinding].inflate(LayoutInflater.from(YourActivity.this))
bottomSheet.setContentView(binding.root)
bottomSheet.behavior.state = BottomSheetBehavior.STATE_EXPANDED
bottomSheet.show()
override fun onStart() {
super.onStart()
bottomSheetBehavior?.skipCollapsed = true
bottomSheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
}
Putting this in BottomSheet helped without setting styles and without ScrollView
(correct me if I'm wrong or if I'm missing something)
This trick solved me
in manifest put
android:windowSoftInputMode="adjustPan"
in your activity
and
bottomSheetDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
bottomSheetDialog.getBehavior().setState(BottomSheetBehavior.STATE_EXPANDED);
For this, I found an AlertDialog worked best. While it doesn't sit flush against the bottom or side of the screen, it still looks good enough.
First, create the AlertDialog with your view.
val view = LayoutInflater.from(context).inflate(R.layout.alert, null)
dialog = AlertDialog.Builder(context)
.setView(view)
.create()
Next, set the gravity.
dialog.window.attributes.gravity = Gravity.BOTTOM
And finally, show it.
dialog.show()
You can also bind the keyboard to stay with the dialog, by using an onDismissListener.
After showing the AlertDialog, I force up the keyboard.
Call this method, passing in your EditText.
fun showKeyboard(view: View?) {
if (view == null) return;
val imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
}
And for dismissing within the onDismissListener.
private fun hideKeyboard() {
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)
}
My answer might be useful for someone who is still looking for solution. If keyboard is covering edittext in BottomSheetDialogFragment then in setupDialog() method create instance of a class KeyboardUtil and pass your rootview.
#Override
public void setupDialog(final Dialog dialog, int style) {
super.setupDialog(dialog, style);
View view = View.inflate(getActivity(), R.layout.reopen_dialog_layout, null);
new KeyboardUtil(getActivity(), view);
}
Create a new class
public class KeyboardUtil {
private View decorView;
private View contentView;
//a small helper to allow showing the editText focus
ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Rect r = new Rect();
//r will be populated with the coordinates of your view that area still visible.
decorView.getWindowVisibleDisplayFrame(r);
//get screen height and calculate the difference with the useable area from the r
int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
int diff = height - r.bottom;
//if it could be a keyboard add the padding to the view
if (diff != 0) {
// if the use-able screen height differs from the total screen height we assume that it shows a keyboard now
//check if the padding is 0 (if yes set the padding for the keyboard)
if (contentView.getPaddingBottom() != diff) {
//set the padding of the contentView for the keyboard
contentView.setPadding(0, 0, 0, diff);
}
} else {
//check if the padding is != 0 (if yes reset the padding)
if (contentView.getPaddingBottom() != 0) {
//reset the padding of the contentView
contentView.setPadding(0, 0, 0, 0);
}
}
}
};
public KeyboardUtil(Activity act, View contentView) {
this.decorView = act.getWindow().getDecorView();
this.contentView = contentView;
//only required on newer android versions. it was working on API level 19
if (Build.VERSION.SDK_INT >= 19) {
decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
/**
* Helper to hide the keyboard
*
* #param act
*/
public static void hideKeyboard(Activity act) {
if (act != null && act.getCurrentFocus() != null) {
InputMethodManager inputMethodManager = (InputMethodManager) act.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(act.getCurrentFocus().getWindowToken(), 0);
}
}
public void enable() {
if (Build.VERSION.SDK_INT >= 19) {
decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
public void disable() {
if (Build.VERSION.SDK_INT >= 19) {
decorView.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
}
}
}
See https://stackoverflow.com/a/61813321/2914140:
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
return dialog
}
But if a layout is not tall enough, you can use https://stackoverflow.com/a/66287187/2914140 instead. It will open BottomSheetDialog almost fullscreen:
<style name="BottomSheetDialogTheme" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:windowSoftInputMode">adjustResize|stateVisible</item>
</style>
Fiddling with BottomSheetDialogFragmentwasn't really worth it. So I just changed it to a simple DialogFragment and just set its gravity to bottom:
window.setGravity(Gravity.BOTTOM);
Worked like a charm.

Android - How to make an AlertDialog narrower than standard?

I currently have the following code to build a wait dialog with a ProgressBar:
LayoutInflater factory = LayoutInflater.from(TherapistActivity.this);
View view = factory.inflate(R.layout.waitdialog, null);
dialog = new AlertDialog.Builder(TherapistActivity.this)
.setView(view)
.setCancelable(false)
.create();
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
WindowManager.LayoutParams wmlp = dialog.getWindow().getAttributes();
wmlp.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
wmlp.x = 0; //x position
wmlp.y = Math.round(metrics.density * 100); //y position
wmlp.width = Math.round(metrics.density * 55); //doesn't appear to work
Here is the XML for my dialog:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="#+id/top"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="55dp"
android:layout_height="55dp"
android:background="#drawable/boxbkg">
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
I would like my dialog to be a small square dialog with just a spinning ProgressBar. However, even with wmlp.width = Math.round(metrics.density * 55), the dialog remains wide.
What is the proper way to get around this?
As far as I know, changing dialog - params / width and height - should take place in the onCreate (set style is needed) and in the onCreateDialog (setting the params).
example of this two methods from a custom DialogFragment which take place on the whole screen without any margin:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, R.style.AppTheme);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
Window w = dialog.getWindow();
w.setBackgroundDrawable(new ColorDrawable(Color.WHITE));
WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
params.verticalMargin = 0;
params.horizontalMargin = 0;
params.x=0;
params.y = 0;
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
params.width= ViewGroup.LayoutParams.MATCH_PARENT;
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
w.setGravity(Gravity.TOP| Gravity.LEFT);
return dialog;
}
Please let me know if it helped you.
I figured it out. It appears that I needed two more lines of code. Before setting the width, I needed this line of code:
wmlp.copyFrom(dialog.getWindow().getAttributes());
And after setting the width, I needed this line of code:
dialog.getWindow().setAttributes(wmlp);
The original code, in combination with the extra code from the answer, doesn't work with my code unfortunately, which might be caused by using a Fragment.
The following code (tested with Java 8/min API 24/target API 27) works with a Fragment and with both portrait and landscape screen orientation. It lets you set the size of the dialog to whatever you like (see below) and there's no need to set its position because in the end it's still just a normal AlertDialog (without buttons or title) with a custom view:
AlertDialog.Builder builder = new AlertDialog.Builder((AppCompatActivity) getActivity());
builder.setView(R.layout.progress_view);
AlertDialog loadingDialog = builder.create();
loadingDialog.show();
loadingDialog.getWindow().setLayout(400,400); //You have to call this after "show"!
//loadingDialog.dismiss();
My progress_view layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/progress_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="#FF0000"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="20dp"
android:paddingEnd="20dp"
android:paddingStart="20dp"
android:paddingTop="20dp">
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
I tried using a LinearLayout before but it didn't work, the dialog still used its original size. The important bit here is match_parent because only that actually centers the progress circle in the AlertDialog. Using wrap_content is going to push it to the top left of the dialog.
The result looks like this:
You can of course add more stuff, like e.g. a "Please wait..." TextView or set the background color to whatever color you want, just two things I noticed:
Transparency doesn't work. If you set the background to e.g. 50% alpha, you can see the white background of the AlertDialog through it. I tried changing the dialog's transparency as suggested here (custom style or getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT))) but, even though it worked, the dialog and ended up losing its rounded corners and got squished.
You have to test what size works for you. 400 by 400 is fine for a default progress circle and some padding but if you make the dialog too small for the view's content, it won't show up at all.

Android Dialog - Rounded Corners and Transparency

I'm trying to make a custom android dialog with rounded corners. My current attempts have given me this result.
As you can see, the corners are rounded, but it leaves the white corner still intact.
Below is the xml that I put in the drawable folder to create the blue dialog with the red border with the rounded corners.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:shape="rectangle">
<solid android:color="#color/transparent_black" />
<corners android:radius="#dimen/border_radius"/>
</shape>
</item>
<item
android:left="#dimen/border_width"
android:right="#dimen/border_width"
android:top="#dimen/border_width"
android:bottom="#dimen/border_width" >
<shape android:shape="rectangle">
<solid android:color="#color/blue" />
<corners android:radius="#dimen/border_radius"/>
</shape>
</item>
</layer-list>
Below is the layout of the dialog.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/fill"
android:orientation="vertical"
android:layout_margin="#dimen/spacing_normal"
android:padding="#dimen/spacing_normal"
android:background="#drawable/border_error_dialog" >
<RelativeLayout
style="#style/block"
android:layout_gravity="center" >
<ImageView
android:id="#+id/imageView1"
style="#style/wrap"
android:layout_alignParentLeft="true"
android:layout_centerHorizontal="true"
android:contentDescription="#string/content_description_filler"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/textView1"
style="#style/error_text"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/imageView1"
android:text="#string/error_login" />
</RelativeLayout>
<Button
android:id="#+id/button1"
style="#style/wrap"
android:layout_gravity="center"
android:text="Button" />
</LinearLayout>
And below is the Activity in which I create the dialog.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b1 = (Button) findViewById(R.id.button1);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MainActivity.this);
View child = getLayoutInflater().inflate(R.layout.dialog_custom_tom, null);
alertDialogBuilder.setView(child);
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
});
}
The only solution I have found is here. Use Dialog instead of AlertDialog and set transparent background:
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
Therefore you can't use the builder. But you can use new Dialog() also in onCreateDialog callback of DialogFragment if you follow to best guidelines.
This works also for Gingerbread.
Besides the layered drawable can be simplified to one shape with xml element <stroke> for the border.
I had similar issue when made dialog extending DialogFragment and to fix this used:
dialog.setStyle(DialogFragment.STYLE_NO_FRAME, 0);
Like this:
public class ConfirmBDialog extends DialogFragment {
public static ConfirmBDialog newInstance() {
ConfirmBDialog dialog = new ConfirmBDialog();
Bundle bundle = new Bundle();
dialog.setArguments(bundle);
return dialog;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// This removes black background below corners.
setStyle(DialogFragment.STYLE_NO_FRAME, 0);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.confirm_dialog, container, true);
getDialog().setCanceledOnTouchOutside(true);
return view;
}
Hope this helps.
Just try
myDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
The below code solved the issue
MyDialog mydialog = new MyDialog(this, "for testing",
new myOnClickListener() {
#Override
public void onPositiveButtonClick() {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(),
"I am positive button in the dialog",
Toast.LENGTH_LONG).show();
}
#Override
public void onNegativeButtonClick() {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(),
"I am negative button in the dialog",
Toast.LENGTH_LONG).show();
}
});
// this will remove rectangle frame around the Dialog
mydialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
mydialog.show();
Thanks,
Nagendra
In you java file keep below code and change your layout name
View mView =LayoutInflater.from(mContext).inflate(R.layout.layout_pob,null);
alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
just try using this, this worked for me
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
Use 9-patch PNG with transparency in those corners.
public void initDialog() {
exitDialog = new Dialog(this);
exitDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
View view = View.inflate(this, R.layout.dialoglayout, null);
exitDialog.setContentView(view);
AdSize adSize = new AdSize(300, 250);
dialogAdview = new AdView(this);
dialogAdview.setAdUnitId(getResources().getString(R.string.banner_id));
dialogAdview.setAdSize(adSize);
RelativeLayout adLayout = (RelativeLayout) view.findViewById(R.id.adLayout);
adLayout.addView(dialogAdview);
AdRequest adRequest = new AdRequest.Builder()
.build();
dialogAdview.loadAd(adRequest);
dialogAdview.setAdListener(new AdListener() {
#Override
public void onAdLoaded() {
Log.d("Tag", "adLoaded");
super.onAdLoaded();
}
});
view.findViewById(R.id.yes_btn).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
exit = true;
onBackPressed();
}
});
view.findViewById(R.id.no_btn).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
exit = false;
exitDialog.dismiss();
}
});
}
dialoglayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/custom_dialog_round"
android:orientation="vertical">
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:text="Do you want to exit?"
android:textColor="#000"
android:textSize="18dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/text"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="#+id/yes_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/background_draw"
android:padding="8dp"
android:text="Yes"
android:textAlignment="center"
android:textColor="#9fa8da"
android:textSize="20dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="#+id/no_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:background="#drawable/background_draw"
android:padding="8dp"
android:text="No"
android:textAlignment="center"
android:textColor="#d50000"
android:textSize="20dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
`
custom_dialog_round.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="#fff"/>
<corners
android:radius="10dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
reference http://techamongus.blogspot.com/2018/02/android-create-round-corner-dialog.html
UPDATE
I understood that activity's background makes sense. So use #robert's answer with these changes.
in DialogFragment layout set width and height or add minimum sizes:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content" // Or match_parent, 300dp.
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:background="#drawable/white_round_corner_background"
android:gravity="center"
android:minWidth="300dp"
android:minHeight="200dp"
android:orientation="vertical"
android:padding="15dp"
>
...
Remove <item name="android:background">#color/...</item> from styles of needed activities and set these backgrounds in activity's layouts.
In DialogFragment write:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// This removes black background below corners.
setStyle(DialogFragment.STYLE_NO_FRAME, 0);
}
Old variant
According to robert answer, you should apply setStyle(STYLE_NO_FRAME, 0), but there appear new problems. If you have a narrow DialogFragment like in Custom dialog too small, then you should follow this guide.
Add to styles.xml these 3 lines for dialog size:
<style name="ErrorDialogTheme" parent="#android:style/Theme.Dialog">
<item name="android:minWidth" type="dimen">300dp</item>
<!-- This option makes dialog fullscreen and adds black background, so I commented it -->
<!-- <item name="android:minHeight" type="dimen">200dp</item> -->
<!-- This option doesn't work, so I commented it -->
<!-- <item name="android:layout_width">match_parent</item> -->
</style>
In layout of your DialogFragment add style:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
android:minWidth="300dp" // Optional, remove this line.
android:minHeight="200dp" // Optional, remove this line.
style="#style/ErrorDialogTheme"
android:theme="#style/ErrorDialogTheme"
>
In code of your DialogFragment write:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// This removes black background. If not 0 as a parameter, black background will appear.
setStyle(STYLE_NO_FRAME, 0)
}
// If you want a fullscreen dialog, use this, but it doesn't remove a black background.
override fun onStart() {
super.onStart()
dialog.window?.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT)
}
Look at AndroidManifest.xml and find all activities that can show these dialogs, check android:theme="..." themes and go to styles.xml. Now take a look at <item name="android:background">#color/...</item> items of these themes. There should be a transparent color or these items might not exist. If you have these background items, whole activities will have those backgrounds and dialogs too! So, if you have a camera activity with DialogFragment above it, you will see this.
Remove background items of needed styles. Also maybe background is set in code, check it.
In Dialog with transparent background in Android and many pages it is written to add one of these:
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(0));
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
probably in onViewCreated() or onCreateDialog(), but it didn't help me, because the background of the Activity was set in styles.
Tested on Samsung Galaxy S4 running Android 5.0.1.
Use CardView and make
app:cardCornerRadius="dp"
According shape xml.
I will post my solution here because it may be helpful. The solution that worked for me was to set the drawable resource in the layout xml and also in the activity that starts the dialog, without switching from AlertDialog to Dialog.
This would mean that in the layout where we create our design for the dialog alert_dialog_design.xml we will have the property android:background filled with our own defined background alert_dialog_shape.xml:
android:background="#drawable/alert_dialog_shape"
But also inside the activity that starts the dialog:
alert.getWindow().setBackgroundDrawableResource(R.drawable.alert_dialog_shape);
This way the parent (the alert itself) of your custom layout will have the shape you desire. Using this method I achieved the following:
https://i.stack.imgur.com/drCw3.png

AlertDialog setCustomTitle styling to match standard AlertDialog title

I'm working on an Android app and I have an AlertDialog subclass. I would like to put 2 ImageButtons on the right side of the title area of the dialog (similar to an the ActionBar in an Activity). I'm using setCustomTitle() to do this, which replaces the title area with a custom view of my own creation. This works fine, but the styling of my custom title area is not the same as the standard title styling (height, color, separator, etc).
My question is: with the understanding that styling varies by OS version and manufacturer, how can I style my custom title in the dialog so that it will match the standard title styling for other AlertDialogs?
Here is an image of anAlertDialog with standard styling (this is from ICS, but I want to be able to match any variant -- not this particular style)
And here is an image of an AlertDialog with custom title and buttons (note how the title height and color don't match the standard dialog)
EDIT: I can't just add the ImageButtons to the standard title view, because I don't have access to it. If you know of a (reliable, non-hack) method for me to add buttons to the standard title area, I would accept that as well.
Given that there is new interest in this question, let me elaborate about how I "solved" this.
First, I use ActionBarSherlock in my app. This is not necessary, I suppose, though it helps a lot because the styles and themes defined in the ABS project allow me to mimic the Holo theme on pre-ICS devices, which provides a consistent experience in the app.
Second, my "dialog" is no longer a dialog -- it's an activity themed as a dialog. This makes manipulation of the view hierarchy simpler, because I have complete control. So adding buttons to the title area is now trivial.
Here are the screenshots (2.2 device and 4.1 emulator). Note that the only significant styling difference is the EditText, which I have chosen not to address.
Here is my onCreate in my dialog activity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_tag);
setTitle(R.string.tag_dialog_title);
View sherlockTitle = findViewById(android.R.id.title);
if (sherlockTitle != null) {
sherlockTitle.setVisibility(View.GONE);
}
View sherlockDivider = findViewById(R.id.abs__titleDivider);
if (sherlockDivider != null) {
sherlockDivider.setVisibility(View.GONE);
}
// setup custom title area
final View titleArea = findViewById(R.id.dialog_custom_title_area);
if (titleArea != null) {
titleArea.setVisibility(View.VISIBLE);
TextView titleView = (TextView) titleArea.findViewById(R.id.custom_title);
if (titleView != null) {
titleView.setText(R.string.tag_dialog_title);
}
ImageButton cancelBtn = (ImageButton) titleArea.findViewById(R.id.cancel_btn);
cancelBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
cancelBtn.setVisibility(View.VISIBLE);
ImageButton okBtn = (ImageButton) titleArea.findViewById(R.id.ok_btn);
okBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// do stuff here
finish();
}
});
okBtn.setVisibility(View.VISIBLE);
}
}
And here is the relevant layout for the activity:
<LinearLayout
android:orientation="vertical"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<LinearLayout
android:id="#+id/dialog_custom_title_area"
android:orientation="vertical"
android:fitsSystemWindows="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingRight="10dp">
<TextView
android:id="#+id/custom_title" style="?android:attr/windowTitleStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minHeight="#dimen/abs__alert_dialog_title_height"
android:paddingLeft="16dip"
android:paddingRight="16dip"
android:textColor="#ffffff"
android:gravity="center_vertical|left" />
<ImageButton
android:id="#+id/ok_btn"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:minWidth="#dimen/abs__action_button_min_width"
android:minHeight="#dimen/abs__alert_dialog_title_height"
android:scaleType="center"
android:src="#drawable/ic_action_accept"
android:background="#drawable/abs__item_background_holo_dark"
android:visibility="visible"
android:layout_gravity="center_vertical"
android:contentDescription="#string/acc_done"/>
<ImageButton
android:id="#+id/cancel_btn"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:minWidth="#dimen/abs__action_button_min_width"
android:minHeight="#dimen/abs__alert_dialog_title_height"
android:scaleType="center"
android:src="#drawable/ic_action_cancel"
android:background="#drawable/abs__item_background_holo_dark"
android:visibility="visible"
android:layout_gravity="center_vertical"
android:contentDescription="#string/acc_cancel"
/>
</LinearLayout>
<View
android:id="#+id/dialog_title_divider"
android:layout_width="fill_parent"
android:layout_height="2dip"
android:background="#color/abs__holo_blue_light" />
</LinearLayout>
<RelativeLayout
android:id="#+id/list_suggestions_layout"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
<!-- this is where the main dialog area is laid out -->
</RelativeLayout>
</LinearLayout>
And finally, in my AndroidManifext.xml, here is how I define my TagActivity:
<activity
android:icon="#drawable/ic_home"
android:name=".activity.TagActivity"
android:theme="#style/Theme.Sherlock.Dialog"/>
OK, maybe it is not the super perfect solution and maybe it is a bad solution, but I tried this on android 2.3.7 and android 4.1.2:
2.3.7 (real device)
4.1.2 (emulator)
We start by creating a dialog Title style to make sure we have some space for our icons:
res/values/dialogstyles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Dialog" parent="#android:style/Theme.Dialog">
<item name="android:windowTitleStyle">#style/MyOwnDialogTitle</item>
</style>
<style name="MyOwnDialogTitle">
<!-- we need to make sure our images fit -->
<item name="android:layout_marginRight">100dp</item>
</style>
</resources>
res/values-v11/dialogstyles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Dialog" parent="#android:style/Theme.Holo.Dialog">
<item name="android:windowTitleStyle">#style/MyOwnDialogTitle</item>
</style>
</resources>
Then we create our DialogFragment with two tricks:
set the style in the onCreate:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, R.style.Dialog);
}
override onCreateView and add our layout (of buttons) to the Dialog (see comments)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//we need the view to remove the tree observer (that's why it is final)
final View view = inflater.inflate(R.layout.dialog_custom, container);
getDialog().setTitle("Shush Dialog");
//register a layout listener to add our buttons
view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#SuppressWarnings("deprecation")
#SuppressLint("NewApi")
#Override
public void onGlobalLayout() {
//inflate our buttons
View menu = LayoutInflater.from(getActivity()).inflate(R.layout.layout_mymenu, null);
//get the root view of the Dialog (I am pretty sure this is the weakest link)
FrameLayout fl = ((FrameLayout) getDialog().getWindow().getDecorView());
//get the height of the root view (to estimate the height of the title)
int height = fl.getHeight() - fl.getPaddingTop() - fl.getPaddingBottom();
//to estimate the height of the title, we subtract our view's height
//we are sure we have the heights btw because layout is done
height = height - view.getHeight();
//prepare the layout params for our view (this includes setting its width)
//setting the height is not necessary if we ensure it is small
//we could even add some padding but anyway!
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, height);
params.gravity = Gravity.RIGHT | Gravity.TOP;
//add the view and we are done
fl.addView(menu, params);
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
else
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
return view;
}
Alright if it just images, then you just have ensure that everything that you create in xml is scaled by density pixels or DP for short. Most simple coding that sets paint are usually set by pixels as well and may need a manual coding version to density pixels.

Categories

Resources