I'm trying to create a view for use in an alert and I can't get wrap_content to work in an alert dialog. I've tried both a LinearLayout and a ConstraintLayout with the same results.
I've tried several things including these from :
val selectView = layoutInflater.inflate(R.layout.font_size_sel, null)
val builder = androidx.appcompat.app.AlertDialog.Builder(this)
builder.setView(selectView)
val dialog = builder.create()
dialog.window!!
.setLayout(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT)
dialog.show()
and
val selectView = layoutInflater.inflate(R.layout.font_size_sel, null)
val builder = androidx.appcompat.app.AlertDialog.Builder(this)
builder.setView(selectView)
val dialog = builder.create()
dialog.setOnShowListener {
dialog.window?.setLayout(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
dialog.show()
and I've from here I've tried:
val selectView = layoutInflater.inflate(R.layout.font_size_sel, null)
val builder = androidx.appcompat.app.AlertDialog.Builder(this)
builder.setView(selectView)
val dialog = builder.create()
val lp = dialog.window!!.attributes
lp.width = WindowManager.LayoutParams.WRAP_CONTENT
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
dialog.window!!.attributes = lp
dialog.show()
I've tried putting the dialog.show() both before and after setting wrap_content in the code above.
I've tried both ConstraintLayout and LinearLayout with the same results.
Both the layout and the textview have wrap_contents for both the width and height.
This is what the design window from AndroidStudio's layout editor says the window should look like:
And this is a snapshot of the device with the debugger's "show padding..." turned on.
I'm stuck. Any ideas out there?? What am I doing wrong?
Thanks
Steve S.
Related
I'm working on a popup to display some basic bluetooth device information using PopupWindow, but I've ran into a problem. Every touch makes the popup dissapear, while some other apps have popups that do not dissapear if you keep holding down touch, which is what I'd like to achieve.
This is my current code:
private fun showDetails() {
val inflater: LayoutInflater = activity?.getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater
val popupView: View = inflater.inflate(R.layout.popup_tigerbuilder_details, null)
popupView.findViewById<TextView>(R.id.tgrbdetdevice_name).text = device.name
if (Build.VERSION.SDK_INT >= 30) {
popupView.findViewById<TextView>(R.id.tgrbdetdevice_nickname).text = device.alias
popupView.findViewById<TextView>(R.id.tgrbdetdevice_nickname).visibility = View.VISIBLE
}
popupView.findViewById<TextView>(R.id.tgrbdetdevice_mac).text = device.address
// create the popup window
val width: Int = LinearLayout.LayoutParams.WRAP_CONTENT
val height: Int = LinearLayout.LayoutParams.WRAP_CONTENT
val focusable = true
val popupWindow = PopupWindow(popupView, width, height, focusable)
popupWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT));
popupWindow.setIgnoreCheekPress()
popupWindow.animationStyle = -1
// show the popup window
// which view you pass in doesn't matter, it is only used for the window tolken
popupWindow.showAtLocation(view?.parent as View, Gravity.CENTER, 0, 0)
popupWindow.dimBehind()
popupView.setOnClickListener {
Log.d("Fragment", it.id.toString())
}
}
/**
* Dim the background when PopupWindow shows
*/
fun PopupWindow.dimBehind() {
val container = contentView.rootView
val context = contentView.context
val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val p = container.layoutParams as WindowManager.LayoutParams
p.flags = p.flags or WindowManager.LayoutParams.FLAG_DIM_BEHIND
p.dimAmount = 0.6f
wm.updateViewLayout(container, p)
}
How do I make a bottomSheet take up the full height of the screen? Setting the peek height has no effect.
Any help would be appreciated.
bottomSheetDialogFragment.getDialog().setOnShowListener((dialog) ->
{
final BottomSheetDialog bottomSheetDialog = (BottomSheetDialog)dialog;
final FrameLayout bottomSheet = bottomSheetDialog.findViewById(R.id.design_bottom_sheet);
if (bottomSheet != null)
{
final BottomSheetBehavior<View> behavior = BottomSheetBehavior.from(bottomSheet);
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
behavior.setPeekHeight(30000); // no effect, bottom sheet does not span entire height of screen
}
});
BottomSheet Layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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:id="#+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<!-- rest of layout not shown -->
<FrameLayout
android:id="#+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/bottomSheetHandle"
tools:layout_height="48dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
You could get the metrics to have access to the height of the screen in pixels and use that reference to set the height of your bottomsheet.
Get Metrics
val metrics = DisplayMetrics()
requireActivity().windowManager?.defaultDisplay?.getMetrics(metrics)
Set state and peekHeight of dialog
bottomSheetDialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
bottomSheetDialog.behavior.peekHeight = metrics.heightPixels
Set height of your view, notice how we are setting this height as the same of the peekHeight of the dialog. I found this the best way when you want a single size for your BottomSheetDialog
bottomSheet.layoutParams.height = metrics.heightPixels
bottomSheet.requestLayout()
at first inside onCreateDialog
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
...
bottomSheetBehavior?.skipCollapsed = true
bottomSheetBehavior?.peekHeight = Resources.getSystem().displayMetrics.heightPixels
bottomSheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
return bottomSheet
}
afterward, use this on start method
/**
* to make sheet height full screen
* */
override fun onStart() {
super.onStart()
val metrics = DisplayMetrics()
requireActivity().windowManager?.defaultDisplay?.getMetrics(metrics)
binding.rootContainer.layoutParams.height = metrics.heightPixels
binding.rootContainer.requestLayout()
}
I hope it works fine because it work correctly with me ;)
to accomplish that you can set match_parent to layout params of bottom
sheet like this:
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = BottomSheetDialog(requireContext(), theme)
dialog.setOnShowListener {
val bottomSheetDialog = it as BottomSheetDialog
val parentLayout =
bottomSheetDialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
parentLayout?.let { it ->
val behaviour = BottomSheetBehavior.from(it)
setupFullHeight(it)
behaviour.state = BottomSheetBehavior.STATE_EXPANDED
}
}
return dialog
}
private fun setupFullHeight(bottomSheet: View) {
val layoutParams = bottomSheet.layoutParams
layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT
bottomSheet.layoutParams = layoutParams
}
}
// add this code into your class
#Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
View bottomSheet = dialog.findViewById(R.id.design_bottom_sheet);
if (dialog != null) {
bottomSheet.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
}
View view = getView();
view.post(() -> {
View parent = (View) view.getParent();
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) (parent).getLayoutParams();
CoordinatorLayout.Behavior behavior = params.getBehavior();
BottomSheetBehavior bottomSheetBehavior = (BottomSheetBehavior) behavior;
bottomSheetBehavior.setPeekHeight(view.getMeasuredHeight());
((View)bottomSheet.getParent()).setBackgroundColor(Color.TRANSPARENT)
});
}
I have a linearlayout in a layout file. I need to show alertdialog inside that linearlayout. How can i achieve this?
I tried this but it doesn't work correctly
llChartPopup.getLocationInWindow(chartPositions)//llChartPopup is sub linearlayout inside my layout file
var viewGroup = findViewById<ContentFrameLayout>(android.R.id.content)
var dialogView = LayoutInflater.from(this).inflate(R.layout.pass_sa_chart_popup, viewGroup, false)
var builder = AlertDialog.Builder(this)
builder.setView(dialogView)
alertDialog = builder.create()
alertDialog.window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
alertDialog.window.setGravity(Gravity.TOP)
var wmlp = alertDialog.window.attributes
wmlp.x = chartPositions[0]
wmlp.y = chartPositions[1]
alertDialog.show()
val alertDialog = AlertDialog.Builder(context)
val customView = LayoutInflater.from(context).inflate(R.layout.dialog_custom_layout, null)
//Your views inside dialog
val btnClose = customView.yourView
alertDialog.setView(customView)
val customDialog = alertDialog.create()
customDialog.show()
I would like to dismiss Anko Dialog when pressing the button defined in my customLayout
val dialog = alert {
val view = layoutInflater.inflate(R.layout.match_stats, null)
val closeButton = view.findViewById<ImageButton>(R.id.closeButton)
closeButton.setOnClickListener { _ -> dialog.dismiss()}
customView = view
}
dialog.show()
I tried above code, unfortunately, I can’t get a reference to dialog in my onClickListener. Do you have any idea how to solve it?
You could declare variable before and assign null:
var dialog: DialogInterface? = null
dialog = alert {
val view = layoutInflater.inflate(R.layout.match_stats, null)
val closeButton = view.findViewById<ImageButton>(R.id.closeButton)
closeButton.setOnClickListener { _ -> dialog?.dismiss()}
customView = view
}.show()
Of course now your dialog variable is muttable and optional.
How to set maximum expanded height in android support design bottom sheet?
The question is an extension to the above question, i want to set the max expanded height of the sheet but dynamically according to the screen size.
I have tried setting new layout params to the view implementing bottomsheet behaviour but it does nothing good.
Please use this and chill :)
const val BOTTOMSHEET_HEIGHT_TO_SCREEN_HEIGHT_RATIO = 0.80 //change according to your requirement
override onCreateDialog() in your bottomsheetFragment
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
dialog.setOnShowListener {
dialog.findViewById<FrameLayout>(com.google.android.material.R.id.design_bottom_sheet)
?.apply {
val maxDesiredHeight =
(resources.displayMetrics.heightPixels * BOTTOMSHEET_HEIGHT_TO_SCREEN_HEIGHT_RATIO).toInt()
if (this.height > maxDesiredHeight) {
val bottomSheetLayoutParams = this.layoutParams
bottomSheetLayoutParams.height = maxDesiredHeight
this.layoutParams = bottomSheetLayoutParams
}
BottomSheetBehavior.from(this)?.apply {
this.state = BottomSheetBehavior.STATE_EXPANDED
this.skipCollapsed = true
}
}
}
return dialog
}
2021
I'm late but someone will need
Kotlin extenxion:
fun View.setupFullHeight(maxHeight: Double = 0.3) {
val displayMetrics = context?.resources?.displayMetrics
val height = displayMetrics?.heightPixels
val maximalHeight = (height?.times(maxHeight))?.toInt()
val layoutParams = this.layoutParams
maximalHeight?.let {
layoutParams.height = it
}
this.layoutParams = layoutParams
}
How to use:
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return object : BottomSheetDialog(requireContext(), R.style.DialogRoundedCornerStyle) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
dialog?.setOnShowListener {
val bottomSheetDialog = it as BottomSheetDialog
val parentLayout =
bottomSheetDialog.findViewById<View>(R.id.design_bottom_sheet)
parentLayout?.let { view ->
val behavior = BottomSheetBehavior.from(view)
view.setupFullHeight()
behavior.apply {
state = BottomSheetBehavior.STATE_EXPANDED
isDraggable = false
isCancelable = false
}
}
}
}
override fun onBackPressed() {
super.onBackPressed()
dialog?.dismiss()
}
}
}
The simplest solution is to set the maxHeight property of the bottom sheet like this.
DisplayMetrics displayMetrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
bottomSheet.setMaxHeight((int) (displayMetrics.heightPixels * 0.65));
Finally found it,
This question troubled me a lot with no solution reported anywhere, and the answer lies in the behavior itself.
The minimum offset is the max value upto which the bottomsheet should move and we set the lower cap of the value to our desired height upto which we want the bottomsheet to move.
You can expose a function to set the value or do it direclty in our behavior.
To dynamically set the max expanded height for bottomsheet we need to increase the minimum offset value from 0 to our desired value in BottomSheetBehavior class, let me show the code.
Happy coding!!
// The minimum offset value upto which your bottomsheet to move
private int mMinOffset;
/**
* Called when the parent CoordinatorLayout is about the layout the given child view.
*/
#Override
public boolean onLayoutChild(CoordinatorLayout parent, V child, int layoutDirection) {
int dynamicHeight = Utils.dpToPx(parent.getContext(), **your_value_in_dp**);
mMinOffset = Math.max(dynamicHeight, mParentHeight - child.getHeight());
mMaxOffset = Math.max(mParentHeight - mPeekHeight, mMinOffset);
mAnchorOffset = Math.min(mParentHeight - mAnchorHeight, mMaxOffset);
if (mState == STATE_EXPANDED) {
ViewCompat.offsetTopAndBottom(child, mMinOffset);
anchorViews(mMinOffset);
}
}