How to set custom layout for AlertDialog? - android

Call my dialog:
alertDialog = showInfoDialog(message = "$wrongPasscodeMessage\n$retryMessage")
And here is the method:
fun FragmentActivity.showInfoDialog(message: String?): AlertDialog? {
return try {
val customLayout = layoutInflater.inflate(R.layout.custom_layout, null)
AlertDialog.Builder(this)
.setView(customLayout)
.setMessage(message)
.setCancelable(false)
.show()
} catch (e: java.lang.Exception) {
e.log()
null
}
}
And here is my custom layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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="match_parent"
android:background="#color/red"
android:paddingStart="#dimen/dp_44"
android:paddingEnd="#dimen/dp_44"
app:cardCornerRadius="#dimen/dp_12" />
But i don't know why my dialog hasn't background red and rounded corners?
What am I missing?
UPDATE:
For example if i change my custom_layout:
<?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="#color/red" >
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="350dp"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:src="#drawable/googleg_disabled_color_18"/>
</LinearLayout>
I get smth like this:
But i want smth like this

You don't need a CardView to achieve a AlertDialog with rounded corners:
Just use the standard constructor:
new MaterialAlertDialogBuilder(this, R.style.DialogOverlay)
.setMessage("Wrong Passcode\nTry again in 5 minutes")
.show();
with a custom theme overlay to center the message:
<style name="DialogOverlay" parent="#style/ThemeOverlay.MaterialComponents.MaterialAlertDialog">
<item name="materialAlertDialogBodyTextStyle">#style/BodyText</item>
</style>
<style name="BodyText" parent="MaterialAlertDialog.MaterialComponents.Body.Text">
<item name="android:gravity">center_horizontal</item>
</style>
If you want to change the rounded corners just add the shapeAppearanceOverlay in your theme overlay:
<style name="DialogOverlay" parent="#style/ThemeOverlay.MaterialComponents.MaterialAlertDialog">
...
<item name="shapeAppearanceOverlay">#style/DialogCorners</item>
</style>
<style name="DialogCorners">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">12dp</item>
</style>

Create a drawable xml of something along the lines of this:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/colorPrimary"/>
<corners android:radius="20dp" />
</shape>
The radius in the shape provides your rounded corners. Now you can set this drawable as the background to your LinearLayout for a dialog, or use a custom <style> in your res/styles.xml:
<style name="CustomAlertDialog" parent="Theme.AppCompat.DayNight.Dialog.Alert">
<item name="android:windowBackground">#drawable/dialog_background</item>
<item name="textAllCaps">false</item>
</style>
and use that style in your AlertDialog.Builder:
AlertDialog.Builder(this, R.style.CustomAlertDialog).setView(...
Using the style allows you to easily use the shape consistently across all your dialogs within the app.

Related

How to change background color of CardView depending if is selected or not?

I'm trying to change the color of a CardView depending if is selected or not
I tried this, this is my card_view_color.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"
android:color="#ABEBC6"/> <!-- selected -->
<item android:state_selected="false"
android:color="#FFFFFF"/> <!-- not selected -->
</selector>
This is my CardView:
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardBackgroundColor="#color/card_view_color"
android:id="#+id/cardViewMetric">
</androidx.cardview.widget.CardView>
Also tried with android:state_activated, android:state_checked and is the same result, not working.
I also have a onClickListener (Kotlin):
holder.binding.root.setOnClickListener{
val GREEN_COLOR = Color.parseColor("#ABEBC6")
holder.binding.cardViewMetric.setCardBackgroundColor(GREEN_COLOR)
}
That has this current behavior.
The wanted behavior I want is only one CardView is gonna be colored, and if I select another one that one is gonna be green and the previous selection is gonna be white.
You can use the MaterialCardView in the Material Components Library.
<com.google.android.material.card.MaterialCardView
...
app:checkedIcon="#null"
android:clickable="true"
android:focusable="true"
android:checkable="true">
</com.google.android.material.card.MaterialCardView>
Then in your code:
card.setChecked(true)
The MaterialCardView extends the androidx.cardview.widget.CardView and support the checking state.
To customize the color you can use the app:cardForegroundColor attribute:
<com.google.android.material.card.MaterialCardView
app:cardForegroundColor="#color/card_selector"
with:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:alpha="...." android:color="#color/..." android:state_checked="true"/>
<item android:alpha="...." android:color="#color/..." app:state_dragged="true"/>
<item android:color="#android:color/transparent" android:state_checked="false" app:state_dragged="false"/>
</selector>
or you can override the colorPrimary in the card:
<com.google.android.material.card.MaterialCardView
android:id="#+id/card"
style="#style/Widget.MaterialComponents.CardView"
with:
<style name="ThemeOverlay.CardView" parent="">
<item name="colorPrimary">#color/....</item>
</style>
By default the checked card has also a checked icon on the top right corner. You can customize it using the app:checkedIcon attribute or you can hide it using app:checkedIcon="#null".
Thanks to the answer of Gabriele Mariotti it gave me an idea:
I changed my CardView to:
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardBackgroundColor="#color/card_view_color"
android:focusableInTouchMode="true"
android:id="#+id/cardViewMetric">
</androidx.cardview.widget.CardView>
(added the focusableInTouchMode attribute)
And in my card_view_color.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"
android:color="#ABEBC6"/> <!-- selected -->
<item android:state_focused="false"
android:color="#FFFFFF"/> <!-- not selected -->
</selector>
And now it has the wanted behavior
EDIT: forgot to say that setOnClickListener is not needed
Hope it helps to anyone=)
Here's the kotlin way :
create an extension function like that:
fun MaterialCardView.managePressed(onClick: () -> Unit) {
this.setOnTouchListener { v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
this.setCardBackgroundColor(context.mutedColor(R.color.onpressed_color))
}
MotionEvent.ACTION_UP -> {
this.setCardBackgroundColor(context.mutedColor(R.color.on_clicked_done_color))
onClick.invoke()
}
MotionEvent.ACTION_CANCEL -> {
this.setCardBackgroundColor(context.mutedColor(R.color.default_color))
}
else -> {
}
}
false
}
Usage:
yourCardView.managePressed() {
//click_listner_call_back_will_be_here
}

android spinner dialog popup background

My android app already set popupbackground as drawable xml. However, the popup dialog still cannot show the color I set. How to settle this issue?
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical"
tools:context=".CountrySelectorActivity">
<Spinner
android:id="#+id/search_spinner1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#color/black"
android:popupBackground="#drawable/spinner_background"
android:spinnerMode="dialog"
/>
<Spinner
android:id="#+id/search_spinner2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:background="#color/black"
android:popupBackground="#drawable/spinner_background"
android:spinnerMode="dialog"/>
</LinearLayout>
#drawable/spinner_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#color/green"/>
</shape>
</item>
</selector>
Spinner activity code
https://stackoverflow.com/questions/51495271/android-kotlin-spinner-working-for-api-23-but-not-working-for-api-21
Make a style using your custom spinner background drawable. Then add the style as an attribute to your spinner. Lastly, programmatically change the spinner popup background color in your activity or fragment. The following way worked for me:
<style name="SpinnerTheme" parent="android:Widget.DeviceDefault.Spinner">
<item name="android:background">#drawable/spinner_background</item>
<item name="android:padding">8dp</item>
<item name="android:paddingTop">5dp</item>
<item name="android:textSize">18sp</item>
<item name="android:textColor">#android:color/white</item>
<item name="android:paddingBottom">5dp</item>
<item name="android:paddingRight">15dp</item>
</style>
Put this in your xml for each spinner (REMOVE android:popupBackground="#drawable/spinner_background" &
android:spinnerMode="dialog"):
<Spinner
android:id="#+id/search_spinner2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:background="#color/black"
style="#style/SpinnerTheme"/>
Then in your activity or fragment, programmatically set the popup background color:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
spinner.setPopupBackgroundResource(R.color.yourColor);
}
Here is a link to example: https://www.oodlestechnologies.com/blogs/Custom-Spinner-In-Android
With AndroidX and using AppCompatSpinner you can do this:
File: styles.xml
<style name="MyPopUpTheme">
<item name="android:background">#color/background_spinner</item>
<item name="android:padding">5dp</item>
<item name="android:textColor">#color/colorAccent</item>
<item name="android:textStyle">bold</item>
</style>
File: Your fragment or Activity
<androidx.appcompat.widget.AppCompatSpinner
android:id="#+id/spinner_years"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="50dp"
android:background="#drawable/spinner_bg"
android:padding="15dp"
android:theme="#style/MyPopUpTheme" />
Result:

BottomSheet - Incorrect Design Behavior

I have been trying to set the Bottomsheet the way Google is using in their apps such as GOOGLE NEWS etc,
This is how Google's Bottomsheet looks like the following
Where my Bottomsheet looks like the following
Stright away you will notice two things,
There are no rounded corners
The navigation at the bottom is not blended
My code for bottomsheet is the following (i removed the controls for simplicity purposes)
MyBottomSheet.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/bottom_sheet"
android:elevation="10dp"
android:minHeight="300dp"
app:behavior_peekHeight="120dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginBottom="30dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--controls here-->
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
And I am calling it in my code as follows
View view = LayoutInflater.Inflate(Resource.Layout.MyBottomSheet, null);
Dialog dialog = new BottomSheetDialog(this);
dialog.SetContentView(view);
How can I get Rounded corners and make sure the bottom navigation does not go transparent?
To get the Google's modal BottomSheet design, implement it the following way. Start by creating a shape drawable which will be used as background for the bottom sheet:
bg_bottomsheet.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:topLeftRadius="#dimen/bottom_sheet_corner_radius"
android:topRightRadius="#dimen/bottom_sheet_corner_radius" />
<padding android:top="#dimen/bottom_sheet_top_padding" />
<solid android:color="#color/white" />
Now create a custom style for the BottomSheet widget.
style-v21.xml
<resources>
<style name="BottomSheetDialogTheme" parent="BaseBottomSheetDialog">
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:navigationBarColor">#color/white</item>
</style>
</resources>
styles.xml
<resources>
<style name="BottomSheet" parent="#style/Widget.Design.BottomSheet.Modal">
<item name="android:background">#drawable/bg_bottom_sheet_dialog_fragment</item>
</style>
<style name="BaseBottomSheetDialog" parent="#style/Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="bottomSheetStyle">#style/BottomSheet</item>
</style>
<style name="BottomSheetDialogTheme" parent="BaseBottomSheetDialog" />
</resources>
Now, extend the BottomSheetDialogFragment and set the new theme on it. That's it!
Now, I use this
<!-- Stuff to make the bottom sheet with round top borders -->
<style name="BottomSheetShapeAppearance" parent="ShapeAppearance.MaterialComponents.LargeComponent">
<item name="cornerFamily">rounded</item>
<item name="cornerSizeTopLeft">16dp</item>
<item name="cornerSizeTopRight">16dp</item>
</style>
<style name="BottomSheetModal" parent="Widget.Design.BottomSheet.Modal">
<item name="shapeAppearance">#style/BottomSheetShapeAppearance</item>
<item name="behavior_peekHeight">140dp</item>
<item name="behavior_fitToContents">true</item>
<item name="behavior_halfExpandedRatio">0.5</item>
</style>
<style name="BaseBottomSheetMenu" parent="Theme.MaterialComponents.DayNight.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="bottomSheetStyle">#style/BottomSheetModal</item>
<item name="android:statusBarColor">#android:color/transparent</item>
</style>
<style name="BottomSheetMenuTheme" parent="#style/BaseBottomSheetMenu" />
You can change general theme support in Theme.MaterialComponents.DayNight.BottomSheetDialogextend by
Theme.MaterialComponents.DayNight.BottomSheetDialog for Dark Mode
In create BotoomSheet load specific theme
override fun getTheme(): Int = R.style.BottomSheetMenuTheme
Try to Use below code
View view = LayoutInflater.Inflate(Resource.Layout.MyBottomSheet, null);
Dialog dialog = new BottomSheetDialog(this);
dialog.SetContentView(view);
((View) view.getParent()).setBackgroundColor(getContext().getResources().getColor(android.R.color.transparent));
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) ((View) view.getParent())
.getLayoutParams();
((View) view.getParent()).setLayoutParams(layoutParams);

Styling dialog boxes in Android

I've been trying to set a basic (not at all custom) dialog box using a fragment, and having difficulties. As you can see in the attached in image, the background shadow isn't correct and the title has white at the left and right hand side.
Following advice from How to style AlertDialogs like a pro I tried setting the alert dialog style through my app, and copying the style out of the Android SDK but this doesn't seem to make much difference.
<!-- Local copy of android:Theme.Holo.Dialog.Alert -->
<style name="Theme_Holo_Dialog_Alert" parent="#android:style/Theme.Holo.Light.Dialog">
<item name="android:windowBackground">#drawable/dialog_full_holo_light</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowActionModeOverlay">true</item>
<item name="android:colorBackgroundCacheHint">#null</item>
<item name="android:buttonBarStyle">#android:style/Holo.Light.ButtonBar.AlertDialog</item>
<item name="android:borderlessButtonStyle">#android:style/Widget.Holo.Light.Button.Borderless.Small</item>
<item name="listPreferredItemPaddingLeft">16dip</item>
<item name="listPreferredItemPaddingRight">16dip</item>
<item name="android:windowMinWidthMajor">#android:dimen/dialog_min_width_major</item>
<item name="android:windowMinWidthMinor">#android:dimen/dialog_min_width_minor</item>
</style>
<!-- Local copy of android:DialogWindowTitle.Holo -->
<style name="DialogWindowTitle_Holo">
<item name="android:maxLines">1</item>
<item name="android:scrollHorizontally">true</item>
<item name="android:textAppearance">#android:style/TextAppearance.Holo.DialogWindowTitle</item>
</style>
and I tried setting the style directly using
ContextThemeWrapper ctw = new ContextThemeWrapper(getActivity(), R.style.Theme_Holo_Dialog_Alert);
AlertDialog.Builder builder = new AlertDialog.Builder(ctw);
and also
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), AlertDialog.THEME_HOLO_LIGHT);
None of which make a difference to the background shadow or the title styling.
Any ideas?
Update 1: The layout of the dialog is set using a fragment and added to the builder as a view:
LayoutInflater inflater = getActivity().getLayoutInflater();
_layoutView = inflater.inflate(R.layout.fragment_edit_cycles, null);
builder.setView(_layoutView);
using the layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="10dp"
android:paddingBottom="20dp"
android:gravity="center_horizontal"
android:orientation="horizontal" >
<NumberPicker
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/editStageCyclesSpin" />
</LinearLayout>
Update 2: Removed the padding and changed the height/width in response to Alok Nair
I removed the padding and changed the layout width and height but unfortunately this had no effect on the white space in the title
<?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">
<NumberPicker
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/editStageCyclesSpin" />
</LinearLayout>

9-patch background adds top and bottom padding. How to avoid it?

I'm trying to customize ToggleButton in my app. I'm setting 9-patch image as background as written here.
And then in my layout xml:
<ToggleButton
android:id="#+id/toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="#drawable/btn_toggle_bg"
android:checked="true"
android:gravity="center_horizontal|center_vertical" />
btn_toogle_bg.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+android:id/background"
android:drawable="#android:color/transparent"/>
<item
android:id="#+android:id/toggle"
android:drawable="#drawable/btn_toggle"/>
</layer-list>
btn_toggle.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/btn_toggle_off" android:state_checked="false"/>
<item android:drawable="#drawable/btn_toggle_on" android:state_checked="true"/>
</selector>
9-patch looks like this (btn_toggle_off):
The same image for checked state.
But when I'm applying this as background I get some unexpected top and bottom padding:
I've got the same result when applying this background to Button or using xml-drawable as background.
How to avoid unexpected padding? Help, please.
Update:
Also, when I'm adding this style to the app theme there is no padding but ToggleButton becames unclickable (doesn't change its state):
styles.xml:
<style name="Widget.Button.Toggle" parent="android:Widget">
<item name="android:background">#drawable/btn_toggle_bg</item>
<item name="android:disabledAlpha">?android:attr/disabledAlpha</item>
</style>
themes.xml:
<style name="MyThemeName" parent="#android:Theme.Black">
<item name="android:buttonStyleToggle">#style/Widget.Button.Toggle</item>
</style>
It seems that I needed to extend android:Widget.Button.Toggle style:
<style name="Widget.Button.Toggle" parent="android:Widget.Button.Toggle">
<item name="android:background">#drawable/btn_toggle_bg</item>
<item name="android:disabledAlpha">?android:attr/disabledAlpha</item>
</style>
The reason for the padding is your right black pixel that describes where the content should be placed, should be the whole length of the image from top to bottom.
try this:

Categories

Resources