I am working on an android application where I am using DialogFragment to display the dialog but its width is very small. How I can make this width to fill_parent to it ?
public class AddNoteDialogFragment extends DialogFragment {
public AddNoteDialogFragment() {
// Empty constructor required for DialogFragment
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getDialog().setTitle(getString(R.string.app_name));
View view = inflater.inflate(R.layout.fragment_add_note_dialog,
container);
return view;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
// request a window without the title
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
}
fragment_add_note_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin" >
<EditText
android:id="#+id/addNoteEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="top"
android:hint="#string/clock_enter_add_note"
android:imeOptions="actionDone"
android:inputType="textCapSentences|textMultiLine"
android:lines="5" />
<Button
android:id="#+id/submit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="#drawable/login_button"
android:text="#string/submit_button"
android:textColor="#android:color/white" />
</LinearLayout>
This is the solution I figured out to handle this issue:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
#Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
}
Edit:
You can use the code below in onCrateView method of Fragment before return the inflated view.
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
Have you tried using the answer of Elvis from How to make an alert dialog fill 90% of screen size?
It is the following:
dialog.getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
Update:
Above code should be added inside onStart() method of the DialogFragment.
This is worked for me
Create your custom style :
<style name="DialogStyle" parent="Base.Theme.AppCompat.Dialog">
<item name="android:windowMinWidthMajor">97%</item>
<item name="android:windowMinWidthMinor">97%</item>
</style>
You can also try use the right parent to match your other dialogs. for example parent="ThemeOverlay.AppCompat.Dialog" and so on.
Use this style in your dialog
public class MessageDialog extends DialogFragment {
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, R.style.DialogStyle);
}
// your code
}
For me, it worked when I replaced the LinearLayout parent of the layout inflated in onCreateView by RelativeLayout. No other code change required.
<!-- A blank view to force the layout to be full-width -->
<View
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_gravity="fill_horizontal" />
in the top of my dialog layout did the trick.
public class FullWidthDialogFragment extends AppCompatDialogFragment {
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, R.style.Theme_AppCompat_Light_Dialog_Alert);
}
}
and if you want much more flexibility can extend AppCompat_Dialog_Alert and custom attributes
Based on other solutions, I have created my own.
<style name="AppTheme.Dialog.Custom" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:windowNoTitle">true</item>
<item name="android:windowMinWidthMajor">100%</item>
<item name="android:windowMinWidthMinor">100%</item>
</style>
abstract class BaseDialogFragment : DialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(DialogFragment.STYLE_NO_TITLE, R.style.AppTheme_Dialog_Custom)
}
}
In my case I also used the following approach:
#Override
public void onStart() {
super.onStart();
getDialog().getWindow().setLayout(LayoutParams.MATCH_PARENT, (int) getResources().getDimension(R.dimen.dialog_height));
}
}
But there were still small gaps between left and right edges of the dialog and the screen edges on some Lollipop+ devices (e.g. Nexus 9).
It was not obvious but finally I figured out that to make it full width across all the devices and platforms window background should be specified inside styles.xml like the following:
<style name="Dialog.NoTitle" parent="Theme.AppCompat.Dialog">
<item name="android:windowNoTitle">true</item>
<item name="android:padding">0dp</item>
<item name="android:windowBackground">#color/window_bg</item>
</style>
And of course this style needs to be used when we create the dialog like the following:
public static DialogFragment createNoTitleDlg() {
DialogFragment frag = new Some_Dialog_Frag();
frag.setStyle(DialogFragment.STYLE_NO_TITLE, R.style.Dialog_NoTitle);
return frag;
}
I want clarify this. Both the ways are right, But with different DialogFragment.
Using android.app.DialogFragment
#Override
public void onStart()
{
super.onStart();
Dialog dialog = getDialog();
if (dialog != null)
{
int width = ViewGroup.LayoutParams.MATCH_PARENT;
int height = ViewGroup.LayoutParams.MATCH_PARENT;
dialog.getWindow().setLayout(width, height);
}
}
Using android.support.v4.app.DialogFragment
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
}
This works for me perfectly.
android:minWidth="300dp"
Through this you can give the width to dialog Fragment.
User AlertDialog.Builder inside your DialogFragment. Add it in onCreateDialog method like this. And in onCreateView do nothing.
public Dialog onCreateDialog(Bundle savedInstanceState)
{
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
View view = LayoutInflater.from(getContext()).inflate(R.layout.gf_confirm_order_timeout_dialog, null);
final Bundle args = getArguments();
String message = args.getString(GfConstant.EXTRA_DATA);
TextView txtMessage = (TextView) view.findViewById(R.id.txt_message);
txtMessage.setText(message);
view.findViewById(R.id.btn_confirm).setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
if (mListener != null)
{
mListener.onDialogConfirmOK();
}
}
});
builder.setView(view);
Dialog dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
Create a custom style in your style.xml file. Just copy paste this code into 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>
</style>
Then in the createDialog method of your DialogFragment, create the dialog object by the code
dialog = new Dialog(getActivity(), R.style.CustomDialog);
This is working for me and hope this will help you too
This is how i solved when i faced this issue. Try this.
in your DialogFragment's onActivityCreated, Add this code according to your need....
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
myview=inflater.inflate(R.layout.fragment_insurance_detail, container, false);
intitviews();
return myview;
}
#Override
public void onActivityCreated(Bundle arg0) {
super.onActivityCreated(arg0);
getDialog().getWindow().getAttributes().windowAnimations = R.style.DialogAnimation;
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
getDialog().getWindow().setGravity(Gravity.CENTER);
}
option 1. add following code in oncreate in activity
getDialog().getWindow()
.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
or you can Create a custom style for Dialog
<style name="CustomDialog" parent="AppTheme" >
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowCloseOnTouchOutside">true</item>
</style>
then use that style in dialog fragment
#Override public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, R.style.CustomDialog);
}
#Override public void onStart() {
super.onStart();
getDialog().getWindow()
.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT);
}
SampleDialogFragment sampleDialogFragment = new SampleDialogFragment();
SampleDialogFragment.show(getActivity().getSupportFragmentManager(), "sometag");
OR you try the following code in style will help you
<item name="android:windowBackground">#null</item>
Solution 2: dialog.window.setLayout
class TestDialog : DialogFragment() {
override fun onStart() {
super.onStart()
dialog?.window?.setLayout(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
}
}
use this 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);
220 is dialog fragment height, change it as u wish
in your layout root, set android:minWidth to a very large value
e.g
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="9999999dp">
...
</LinearLayout>
I end up with a decent solution for this issue.
Based in #Владислав-Стариков answer.
First you need to create Theme overlay where AppTheme is your main theme so it will apply the same attributes in your main theme like the following:
<style name="AppTheme.DialogOverlay" parent="ThemeOverlay.AppCompat.Dialog.Alert">
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">#color/transparent</item>
<item name="android:windowMinWidthMajor">50%</item>
<item name="android:windowMinWidthMinor">90%</item>
</style>
Then override onCreate in your DialogFragment class
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NORMAL, R.style.AppTheme_DialogOverlay)
}
I tried multiple answers listed above; they didn't work for me.
This is the solution to my issue:
In DialogFragment(), add the codes below:
override fun onResume() {
super.onResume()
if (showsDialog) {
val width = ViewGroup.LayoutParams.MATCH_PARENT
val height = ViewGroup.LayoutParams.WRAP_CONTENT
dialog?.window?.apply {
setBackgroundDrawable(ColorDrawable(Color.WHITE))
attributes.gravity = Gravity.BOTTOM
setLayout(width, height)
}
}
}
A clearer and more flexible approach is to set a percentage of the screen's width. Can do the same for the height and it's easy to change.
override fun onResume() {
super.onResume()
dialog?.window?.let { window ->
val params: ViewGroup.LayoutParams = window.attributes
params.width = context?.getScreenSize(false)?.x?.times(0.9)?.toInt()
?: ViewGroup.LayoutParams.MATCH_PARENT
params.height = ViewGroup.LayoutParams.WRAP_CONTENT
window.attributes = params as WindowManager.LayoutParams
}
}
It goes full width, if ConstraintLayout is used as a root layout, without any additional code.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
</androidx.constraintlayout.widget.ConstraintLayout>
Related
I'm trying to set a height peek from which the dialog must start, then the user if dragged should be able to expand it, the issue is that in any case the bottomsheet initial state get half of screen.
The BottomSheet looks like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/varianti_preferite_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:elevation="8dp"
app:behavior_peekHeight="200dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<ImageButton
android:id="#+id/closeButton"
style="#style/Widget.AppCompat.ImageButton"
android:minWidth="75dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="#drawable/bottom_border_radius"
android:contentDescription="#string/bottom_sheet_close_button"
android:padding="10dp"
android:layout_marginBottom="16dp"
app:srcCompat="#drawable/ic_baseline_close" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/variantiRecycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:clipToPadding="false"
android:scrollbars="vertical"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="4"
tools:listitem="#layout/varianti_preferite">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
What i've tried:
I've tried to override onCreateDialog and set HalfExpanded ratio manually but nothing changed:
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
BottomSheetDialog dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
dialog.setOnShowListener(dialog1 -> {
BottomSheetDialog d = (BottomSheetDialog) dialog1;
FrameLayout bottomSheet = (FrameLayout) d.findViewById(com.google.android.material.R.id.design_bottom_sheet);
BottomSheetBehavior<FrameLayout> bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetBehavior.setHalfExpandedRatio(0.2f);
bottomSheetBehavior.setFitToContents(false);
});
return dialog;
}
Kotlin answers are welcome too.
The way that successfully works for me:
Add viewTreeObserver.addOnGlobalLayoutListener in onCreate to setup your BottomSheet behavior:
binding.root.viewTreeObserver.addOnGlobalLayoutListener {
setupBottomSheetBehaviorForView(binding.bottomFragmentContainer)
}
Setup behavior:
private fun setupBottomSheetBehaviorForView(view: FragmentContainerView) {
val behavior = BottomSheetBehavior.from(view)
val screenHeight =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
windowManager.currentWindowMetrics.bounds.height()
} else {
val metrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(metrics)
metrics.heightPixels
}
val toolbarLocation = IntArray(COORDINATES_ARRAY_SIZE) // was added to avoid overlapping the toolbar
binding.toolbar.getLocationOnScreen(toolbarLocation) // with the bottom sheet (in case of full screen activity)
behavior.apply {
peekHeight = (screenHeight * BOTTOM_SHEET_PEEK_PERCENT).toInt()
isFitToContents = false
halfExpandedRatio = BOTTOM_SHEET_PEEK_PERCENT
expandedOffset = toolbarLocation[1] // it's optional
}
}
where BOTTOM_SHEET_PEEK_PERCENT is Float const, for 40% initial peek height:
const val BOTTOM_SHEET_PEEK_PERCENT = 0.40f
I had struggled with a similar problem, my solution was to set layoutParams
Hope it works for you as well
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewBinding.apply {
bottomSheetConstraintLayout.layoutParams.height =
resources.displayMetrics.heightPixels
}
}
I've solved the issue by setting peek height in BottomSheet style.
So in style.xml
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="bottomSheetDialogTheme">#style/AppBottomSheetDialogTheme</item>
</style>
<style name="AppBottomSheetDialogTheme" parent="Theme.Design.Light.BottomSheetDialog">
<item name="bottomSheetStyle">#style/AppModalStyle</item>
</style>
<style name="AppModalStyle" parent="Widget.Design.BottomSheet.Modal">
<item name="android:background">#drawable/bottom_sheet_rounded</item>
<item name="behavior_peekHeight">#dimen/peek_height</item>
</style>
Where in dimens.xml
<dimen name="peek_height">200dp</dimen>
But the issue is that it will set the peek_height to all BottomSheets of the application.
There are more fields below the keyboard. This happened when i updated the support library. I know it's Kotlin but it looks almost the same as java. How do I fix this issue?
This is what it looks like:
My code:
class ProjectsEditBottomSheetFragment(val privateID: String,
val publicID: String) : BottomSheetDialogFragment() {
private val mBottomSheetBehaviorCallback = object : BottomSheetBehavior.BottomSheetCallback() {
override fun onStateChanged(bottomSheet: View, newState: Int) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
dismiss()
}
}
override fun onSlide(bottomSheet: View, slideOffset: Float) {
if (slideOffset < -0.15f) {
dismiss()
}
}
}
override fun setupDialog(dialog: Dialog, style: Int) {
super.setupDialog(dialog, style)
val view = View.inflate(context, R.layout.projects_edit_sheet, null)
dialog.setContentView(view)
dialog.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
val params = (view.parent as View).layoutParams as CoordinatorLayout.LayoutParams
val behavior = params.behavior
if (behavior != null && behavior is BottomSheetBehavior<*>) {
behavior.setBottomSheetCallback(mBottomSheetBehaviorCallback)
}
// Get and set values
val realm = Realm.getDefaultInstance()
val realmObject = realm.where(ProjectsRealmObject::class.java)
.equalTo("privateID", privateID)
.findFirst()
realm.beginTransaction()
view.title_input.text = SpannableStringBuilder(realmObject.title)
view.description_input.text = SpannableStringBuilder(realmObject.description)
view.public_checkbox.isChecked = realmObject.isPublic
realm.commitTransaction()
// Keyboard
view.title_input.onFocusChangeListener = View.OnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
(context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).showSoftInput(view.title_input, InputMethodManager.SHOW_FORCED)
} else {
(context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(view.title_input.windowToken, 0)
}
}
view.description_input.onFocusChangeListener = View.OnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
(context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).showSoftInput(view.description_input, InputMethodManager.SHOW_FORCED)
} else {
(context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(view.description_input.windowToken, 0)
}
}
// Click listners
view.public_layout.setOnClickListener { view.public_checkbox.toggle() }
view.cancel.setOnClickListener {
view?.hideKeyboard()
dismiss()
}
view.save.setOnClickListener {
view?.hideKeyboard()
// Save to realm
realm.beginTransaction()
realmObject.title = if (view.title_input.text.toString() == "") getString(R.string.unnamed) else view.title_input.text.toString()
realmObject.description = view.description_input.text.toString()
realmObject.isPublic = view.public_checkbox.isChecked
realmObject.synced = false
realmObject.updatedRealm = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()).toString() + ""
realm.commitTransaction()
ProjectsSync(context)
toast("Sparat")
dismiss()
}
}
}
xml:
<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="#color/white"
app:layout_collapseMode="none"
app:behavior_hideable="false"
app:behavior_peekHeight="100dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
style="#style/Widget.Design.BottomSheet.Modal">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/content">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingRight="16dp"
android:paddingLeft="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/edit_info_placeholder_title"
android:id="#+id/title_input"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingRight="16dp"
android:paddingLeft="16dp">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/edit_info_placeholder_description"
android:id="#+id/description_input"/>
</android.support.design.widget.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:clickable="true"
android:background="#drawable/click"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:id="#+id/public_layout">
<android.support.v7.widget.AppCompatCheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:id="#+id/public_checkbox"
android:layout_marginRight="8dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/edit_info_placeholder_is_public"
android:layout_gravity="center_vertical"
style="#style/textMedium"/>
</LinearLayout>
<!-- Buttons -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="right"
android:paddingBottom="8dp">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/edit_info_button_cancel"
android:id="#+id/cancel"
style="#style/Widget.AppCompat.Button.Borderless.Colored"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/edit_info_button_save"
android:id="#+id/save"
style="#style/Widget.AppCompat.Button.Borderless.Colored"/>
</LinearLayout>
</LinearLayout>
</FrameLayout>
I found the solution for 27 api. So the reason why keyboard hides view even with SOFT_INPUT_ADJUST_RESIZE is that the windowIsFloating is set for Dialogs.
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:
I tried all of answers in this topic but nothing helped. I looked through many sites and found only one solution that working for me.
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState)
dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
dialog.setOnShowListener {
Handler().post {
val bottomSheet = (dialog as? BottomSheetDialog)?.findViewById<View>(R.id.design_bottom_sheet) as? FrameLayout
bottomSheet?.let {
BottomSheetBehavior.from(it).state = BottomSheetBehavior.STATE_EXPANDED
}
}
}
return dialog
}
Original solution
You can use the next class:
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.BottomSheetDialog;
import android.support.design.widget.BottomSheetDialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
public class TestBottomSheetDialog extends BottomSheetDialogFragment {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View fragmentView = LayoutInflater.from(getContext()).inflate(R.layout.fragment_bottom_sheet, container, false);
if (getDialog().getWindow() != null) {
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
}
if (getActivity() != null) {
View decorView = getActivity().getWindow().getDecorView();
decorView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
Rect displayFrame = new Rect();
decorView.getWindowVisibleDisplayFrame(displayFrame);
int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
int heightDifference = height - displayFrame.bottom;
if (heightDifference != 0) {
if (fragmentView.getPaddingBottom() != heightDifference) {
fragmentView.setPadding(0, 0, 0, heightDifference);
}
} else {
if (fragmentView.getPaddingBottom() != 0) {
fragmentView.setPadding(0, 0, 0, 0);
}
}
});
}
getDialog().setOnShowListener(dialog -> {
BottomSheetDialog d = (BottomSheetDialog) dialog;
View bottomSheetInternal = d.findViewById(android.support.design.R.id.design_bottom_sheet);
if (bottomSheetInternal == null) return;
BottomSheetBehavior.from(bottomSheetInternal).setState(BottomSheetBehavior.STATE_EXPANDED);
});
return fragmentView;
}
}
This is working for me
public class CustomBottomSheetDialogFragment extends BottomSheetDialogFragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
View v = inflater.inflate(R.layout.content_dialog_bottom_sheet, container, false);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
return v;
}
This solution worked for me after spending 5 hours without luck:
Step #1:
Add this code to your styles.xml (located in res\values folder)
<style name="CustomizedBottomDialogStyle">
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:backgroundDimAmount">0.7</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowAnimationStyle">#android:style/Animation.Dialog</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowSoftInputMode">adjustResize</item>
<item name="android:background">#android:color/transparent</item>
</style>
The key here is to set android:windowIsFloating -> false, if it is true your code will not work! Therefor i used rather android:backgroundDimEnabled and android:backgroundDimAmount to make background looks transparent with beautiful overlay.
Step #2:
Write this function to adjust it programmatically (note it is not optional, you need to perform both steps #1 and #2):
private fun showDialog() {
BottomSheetDialog(requireActivity(), R.style.CustomizedBottomDialogStyle).apply {
window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
setOnShowListener {
Handler().post {
val bottomSheet = findViewById<View>(R.id.design_bottom_sheet) as? FrameLayout
bottomSheet?.let {
BottomSheetBehavior.from(it).state = STATE_EXPANDED
}
}
}
setContentView(R.layout.dialog_layout)
// Your code goes here....
show()
}
}
The answer to the highest score is partly right. In my case, 90% of the view is visible after the same style is set. Finally, I made it completely visible through the following solution:
editText.setOnFocusChangeListener { v, hasFocus ->
if (hasFocus) {
(this#****BottomSheetDialogFragment.dialog as BottomSheetDialog).behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
}
add this to your styles
<style name="DialogStyle">
<item name="android:windowBackground">#android:color/transparent</item>
<item name="colorPrimaryDark">#android:color/transparent</item>
</style>
then in your's bottom sheet dialog's onCreate() add
setStyle(DialogFragment.STYLE_NO_FRAME, R.style.DialogStyle);
also don't forget to add to dialog's setupDialog() method
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
MyCustomDialogFragment always wraps it's content and does not keep the min width like a Alertdialog. How can I set the width to respond as a standard Android dialog ?
This is the function I call to display the dialog:
private void displayDialogEdit(String title, String edit,
MyCustomEditDialog.MyCustomEditDialogListener listener, boolean onlyNumbers){
MyCustomEditDialog dialog = MyCustomEditDialog.newInstance(title, edit, onlyNumbers);
dialog.setInterface(listener);
dialog.show(getSupportFragmentManager(), "edit");
}
This is MyCustomDialogFragment.
public class MyCustomEditDialog extends DialogFragment {
private MyCustomEditDialog.MyCustomEditDialogListener mInterface;
public static MyCustomEditDialog newInstance(String title, String editText, boolean onlyNumbers){
MyCustomEditDialog dialog = new MyCustomEditDialog();
Bundle args = new Bundle();
args.putString("title", title);
args.putString("edit", editText);
args.putBoolean("numbers", onlyNumbers);
dialog.setArguments(args);
return dialog;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_edit_dialog, container);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
// Bundle args = getArguments();
//
// boolean numbers = args.getBoolean("numbers");
//
// TextView txt = (TextView)v.findViewById(R.id.title);
// txt.setText(args.getString("title"));
//
// final EditText edit = (EditText) v.findViewById(R.id.editText);
// edit.setText(args.getString("edit"));
//
// if (numbers) edit.setInputType(InputType.TYPE_CLASS_NUMBER);
//
// Button btn = (Button)v.findViewById(R.id.save);
//
// btn.setOnClickListener(new View.OnClickListener() {
// #Override public void onClick(View view) {
// if (mInterface!=null) mInterface.customDialogOnClick(edit.getText().toString());
// }
// });
//
// setCancelable(true);
return v;
}
public void setInterface(MyCustomEditDialog.MyCustomEditDialogListener listener){
this.mInterface = listener;
}
public interface MyCustomEditDialogListener {
void customDialogOnClick(String result);
}
}
This is my layout for the custom dialog
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="#dimen/activity_horizontal_margin"
android:paddingEnd="#dimen/activity_horizontal_margin"
android:gravity="center_horizontal"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:textColor="#color/blue_dark"
android:textStyle="bold"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:layout_marginBottom="10dp"
android:id="#+id/title"
android:layout_gravity="center_horizontal" />
<EditText
android:layout_marginStart="#dimen/activity_horizontal_margin"
android:layout_marginEnd="#dimen/activity_horizontal_margin"
android:layout_marginBottom="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/editText"
android:inputType="text"
/>
<Button
style="#style/btnBasic.blue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/save"
android:id="#+id/save" />
</LinearLayout>
Sample of result:
Found a simple solution to keep the standard with of a alertDialog on a fragmentDialog.
Override the onCreate method from the fragment with this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Material_Light_Dialog_Alert);
}
Try these method
set layout width and height in code by
alertDialog.getWindow().setLayout(600, 400);
set on your main theme for dialog
android:theme="#android:style/Theme.Dialog"
Theme
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:dialogTheme">#style/dialog_light</item>
</style>
<style name="dialog_light" parent="#android:style/Theme.Dialog">
<item name="#android:windowBackground">#color/whitegrey</item>
<item name="#android:textColor">#color/black</item>
</style>
Set theme In code Also like that
new AlertDialog.Builder(
new ContextThemeWrapper(context, android.R.style.Theme_Dialog))
I came across this issue today and I found an easy solution: you can override the getTheme() method from DialogFragment and return R.style.Theme_AppCompat_Light_Dialog_Alert from it (or any other theme you want, I used the AppCompat one so this will work in older versions of Android).
Example code in Kotlin:
class ExampleDialog : DialogFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.example_dialog, container, false)
}
override fun getTheme(): Int {
return R.style.Theme_AppCompat_Light_Dialog_Alert
}
}
Material guidelines describe the behavior of a full-screen dialog.
Full-screen dialog | Dialogs - Material Design
How can I achieve this in practice?
The answer from Boss is correct, but missing the requested action bar as displayed on link in the question.
So, full example below.
Dialog fragment:
public class AKDialogFragment extends DialogFragment {
private static final String TAG = "AKDialogFragment";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.dialog_ak, container, false);
Toolbar toolbar = (Toolbar) rootView.findViewById(R.id.toolbar);
toolbar.setTitle("Dialog title");
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
actionBar.setHomeAsUpIndicator(android.R.drawable.ic_menu_close_clear_cancel);
}
setHasOptionsMenu(true);
return rootView;
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
getActivity().getMenuInflater().inflate(R.menu.menu_ak, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_save) {
// handle confirmation button click here
return true;
} else if (id == android.R.id.home) {
// handle close button click here
dismiss();
return true;
}
return super.onOptionsItemSelected(item);
}
}
Layout dialog_ak.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
<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="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Your content here"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
Menu menu_ak.xml
<menu 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">
<item
android:id="#+id/action_save"
android:orderInCategory="100"
android:title="Save"
app:showAsAction="always"/>
</menu>
Hosting activity must extend AppCompatActivity. Launching dialog is the same as in Boss answer:
FragmentManager fragmentManager = getSupportFragmentManager();
AKDialogFragment newFragment = new AKDialogFragment();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.add(android.R.id.content, newFragment).addToBackStack(null).commit();
I hope it helps someone.
Use DialogFragment
Refer this link for Showing a Dialog Fullscreen or as an Embedded Fragment
http://developer.android.com/guide/topics/ui/dialogs.html#FullscreenDialog
I am just copying the code here.
Create a dialogfragment
public class CustomDialogFragment extends DialogFragment {
/** The system calls this to get the DialogFragment's layout, regardless
of whether it's being displayed as a dialog or an embedded fragment. */
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout to use as dialog or embedded fragment
return inflater.inflate(R.layout.purchase_items, container, false);
}
/** The system calls this only when creating the layout in a dialog. */
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// The only reason you might override this method when using onCreateView() is
// to modify any dialog characteristics. For example, the dialog includes a
// title by default, but your custom layout might not need it. So here you can
// remove the dialog title, but you must call the superclass to get the Dialog.
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
}
Then add this method to show the dialog
public void showDialog() {
FragmentManager fragmentManager = getSupportFragmentManager();
CustomDialogFragment newFragment = new CustomDialogFragment();
if (mIsLargeLayout) {
// The device is using a large layout, so show the fragment as a dialog
newFragment.show(fragmentManager, "dialog");
} else {
// The device is smaller, so show the fragment fullscreen
FragmentTransaction transaction = fragmentManager.beginTransaction();
// For a little polish, specify a transition animation
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
// To make it fullscreen, use the 'content' root view as the container
// for the fragment, which is always the root view for the activity
transaction.add(android.R.id.content, newFragment)
.addToBackStack(null).commit();
}
}
The main thing that has to be focused is in this line
transaction.add(android.R.id.content, newFragment).addToBackStack(null).commit();
The dialog become fullscreen when u specifiy the rootview as the android.R.id.content
try this code:
Dialog yourDialog=new Dialog(this,android.R.styleTheme_Black_NoTitleBar_Fullscreen)
I want to use this theme in my preference activity because of the nice checkbox but my action bar isn't showing.
If you don't want to use PreferenceFragment inside an ActionBarActivity and still want to use your existing PreferenceActivity with AppCompat Support Library v7, you can use to use Toolbar and override PreferenceActvity.setContentView() with a customized layout
You can use Toolbar support while maintaining the current PreferenceActivity and it works well for 2.3.4 and above
private Toolbar mActionBar;
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.Theme_MyApp_Settings);
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
mActionBar.setTitle(getTitle());
//other things to create/init
}
public void setContentView(int layoutResID) {
ViewGroup contentView = (ViewGroup) LayoutInflater.from(this).inflate(
R.layout.settings_activity, new LinearLayout(this), false);
mActionBar = (Toolbar) contentView.findViewById(R.id.action_bar);
mActionBar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
ViewGroup contentWrapper = (ViewGroup) contentView.findViewById(R.id.content_wrapper);
LayoutInflater.from(this).inflate(layoutResID, contentWrapper, true);
getWindow().setContentView(contentView);
}
settings_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/action_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize" />
<FrameLayout
android:id="#+id/content_wrapper"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
styles.xml
<style name="Theme.MyApp.Settings" parent="#style/Theme.AppCompat">
<item name="android:windowNoTitle">true</item>
<item name="toolbarStyle">#style/Widget.Toolbar</item>
</style>
<style name="Widget.Toolbar" parent="#style/Widget.AppCompat.Toolbar">
<item name="android:background">?attr/colorPrimary</item>
<item name="navigationIcon">?attr/homeAsUpIndicator</item>
</style>
PreferenceActivity does not extend ActionBarActivity, which is required for action bar to be available.
If you need a preferences screen with action bar, try to use PreferenceFragment inside an ActionBarActivity instead.
public class SettingsActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment())
.commit();
}
}
public static class SettingsFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
}
...
}
Reference: http://developer.android.com/guide/topics/ui/settings.html#Fragment