How to change selected BottomNavigationView icon size - android

I am using native BottomNavigationView and I want to change selected icon size bigger than unselected icon sizes. (exp. selected icon 40dp, other icon sizes 20dp).
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_centerVertical="true"
android:scaleType="center"
style="#style/Widget.Design.BottomNavigationView"
app:labelVisibilityMode="unlabeled"
app:menu="#menu/navigation_menu" />
<item
android:id="#+id/homePageFragment"
android:icon="#drawable/selector_nav_home"
android:orderInCategory="1"
android:title="" />
<item
android:id="#+id/discoverPageFragment"
android:icon="#drawable/selector_nav_discover"
android:orderInCategory="2"
android:title="" />
<item
android:id="#+id/qrPageFragment"
android:icon="#drawable/selector_nav_qr"
android:orderInCategory="3"
android:title="" />
<item
android:id="#+id/myAccountFragment"
android:icon="#drawable/selector_nav_profile"
android:orderInCategory="4"
android:title="" />
<item android:drawable="#drawable/ic_bottom_navigation_profile" android:state_checked="true"/>
<item android:drawable="#drawable/ic_navigation_profile" android:state_checked="false"/>

You can change text size of selected item like this:
styles.xml:
<style name="bottomNavigationView.Active" parent="#style/TextAppearance.AppCompat.Caption">
<item name="android:textSize">16sp</item>
</style>
bottom_navigation_view.xml:
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.bottomnavigation.BottomNavigationView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/bottomNavView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
app:menu="#menu/bottom_nav_menu"
app:labelVisibilityMode="labeled"
app:itemIconSize="24dp"
android:scaleType="center"
app:itemTextAppearanceActive="#style/bottomNavigationView.Active" />
As a result of increased text size the selected item's icon lifts up and as a whole this looks like the selected element was increased in size:
like this

Try this to change the selected item icon size
override fun onNavigationItemSelected(item: MenuItem): Boolean {
changeItemIconSize(item.itemId)
return true
}
private fun changeItemIconSize(selectedItemId: Int) {
val displayMetrics = resources.displayMetrics
val menuView = bottomMenu.getChildAt(0) as BottomNavigationMenuView
bottomMenu.itemIconSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24f, displayMetrics).toInt()
val iconViewSelected =
menuView.findViewById<View>(selectedItemId).findViewById<View>(com.google.android.material.R.id.icon)
val layoutParams = iconViewSelected.layoutParams
layoutParams.height =
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 32f, displayMetrics).toInt()
layoutParams.width =
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 32f, displayMetrics).toInt()
iconViewSelected.layoutParams = layoutParams
}

Related

Unable to add a view programmatically

<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginHorizontal="#dimen/para"
android:layout_weight="0.5"
android:background="#color/gray_medium_dark"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:id="#+id/messages_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout style="#style/hor_layout">
<TextView
style="#style/message_text"
android:background="#color/gray_blue_medium"
android:text="#string/dummy_short" />
<Space style="#style/message_space" />
</LinearLayout>
</LinearLayout>
</ScrollView>
Above is my xml and I want to add a LinearLayout packed with a TextView and Space to the LinearLayout with the id messages_parent. I want it to happen when a button is pressed.
private fun sendMessage(message: String) {
var newMessage: LinearLayout = LinearLayout(context)
newMessage.style(R.style.hor_layout)
// <style name="hor_layout">
// <item name="android:layout_width">match_parent</item>
// <item name="android:layout_height">wrap_content</item>
// <item name="android:orientation">horizontal</item>
// </style>
var newMessageTxt: TextView = TextView(context)
newMessageTxt.style(R.style.message_text)
newMessageTxt.text = message
// <style name="message_text" parent="myText">
// <item name="android:layout_width">0dp</item>
// <item name="android:layout_height">wrap_content</item>
// <item name="android:layout_weight">0.85</item>
// <item name="android:layout_margin">#dimen/sec</item>
// <item name="android:padding">#dimen/sec</item>
// <item name="android:background">#color/gray_blue_medium</item>
// </style>
// message_text's parent
// <style name="myText">
// <item name="android:textColor">#color/gray_light</item>
// <item name="fontFamily">monospace</item>
// <item name="android:lineSpacingExtra">4sp</item>
// <item name="android:letterSpacing">0.1</item>
// <item name="android:textSize">#dimen/para</item>
// I've checked all my dimens are correct.
// </style>
// setting height by the lines below won't help either
// newMessageTxt.layoutParams.height = 500
// newMessageTxt.height = 500
println("orientation: ${newMessage.orientation.toString()}\n" +
"text size: ${newMessageTxt.textSize}\n" +
"text: ${newMessageTxt.text}\n" +
"height: ${newMessageTxt.height}\n" +
"width: ${newMessageTxt.width}")
// log-
// 2021-03-27 11:32:48.428 31468-31468/com.example.firechat3 I/System.out: orientation: 0
// 2021-03-27 11:32:48.428 31468-31468/com.example.firechat3 I/System.out: text size: 32.0
// 2021-03-27 11:32:48.428 31468-31468/com.example.firechat3 I/System.out: text: Why am I invisible??
// 2021-03-27 11:32:48.428 31468-31468/com.example.firechat3 I/System.out: height: 0
// 2021-03-27 11:32:48.428 31468-31468/com.example.firechat3 I/System.out: width: 0
var newMessageSpace: Space = Space(context)
newMessageSpace.style(R.style.message_space)
// <style name="message_space">
// <item name="android:layout_width">0dp</item>
// <item name="android:layout_height">match_parent</item>
// <item name="android:layout_weight">0.15</item>
// </style>
// adding the TextView and Space to the new LinearLayout
newMessage.addView(newMessageTxt)
newMessage.addView(newMessageSpace)
// adding the new LinearLayout to the parent
requireView().findViewById<LinearLayout>(R.id.messages_parent).addView(newMessage)
}
But the height and width of the newly added views remain 0 no matter how I try to do it and the orientation too whether I set it horizontal or vertical. I am using a package Paris by airbnb to set the style as told in this story on medium and I am using Paris because the solutions from this thread didn't helped me. The first message is added before runtime in the xml by hand and I want the other messages to look like that.
Create an xml file in layout folder named item.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="wrap_content"
android:orientation="horizontal">
<TextView
style="#style/message_text"
android:background="#color/gray_blue_medium"
android:text="#string/dummy_short" />
<Space style="#style/message_space" />
</LinearLayout>
your main xml will look like this
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginHorizontal="#dimen/para"
android:layout_weight="0.5"
android:background="#color/gray_medium_dark"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:id="#+id/messages_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</ScrollView>
In onCreate() get reference to your linear layout
LinearLayout newMessage;
View view=null;
#Override
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
newMessage = findViewById(R.id.messages_parent);
------
------
------
//Then on the click event (where you want to add item in your main container) Infalte item.xml as follows (this code is in java)
view = LayoutInflater.from(YourActivity.this).inflate(R.layout.item,newMessage,false);
TextVIew msgText = view.findViewById(R.id.message_text);
msgText.setText("some new message");
newMessage.addView(view);
}

Disabled color state of Material button

The Material Spec shows a disabled button state that looks greyed out.
https://www.material.io/design/components/buttons.html#toggle-button
I am using the MaterialButton from the material components from Android:
https://www.material.io/develop/android/components/material-button/
However when setting the button to disabled the color/tint of the button does not change.
<com.google.android.material.button.MaterialButton
android:id="#+id/disabled_material_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:text="#string/button_label_disabled"/>
Just not implemented in Material Android Components by default? Does Material Components define a disabled button statelist?
Create the folder /res/color (in your res directory).
Add a new color resource file here, named something like color_states_materialbutton.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false"
android:color="#color/colorDisabled" />
<item android:color="#color/colorEnabled" />
</selector>
Create a style in styles.xml with one of the Widget.MaterialComponents.Button styles as its parent and your color state list as the backgrountTint tag:
<style name="MaterialButtonStyle" parent="Widget.MaterialComponents.Button.UnelevatedButton">
<item name="backgroundTint">#color/color_states_materialbutton</item>
</style>
Set your style on the MaterialButton in your layout:
<com.google.android.material.button.MaterialButton
style="#style/MaterialButtonStyle"
android:id="#+id/disabled_material_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:text="#string/button_label_disabled"/>
With the default style Widget.MaterialComponents.Button the default selector used as backgroundTint handles the disabled state without any changes:
It is the default selector:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorPrimary" android:state_enabled="true"/>
<item android:alpha="0.12" android:color="?attr/colorOnSurface"/>
</selector>
Just use:
<com.google.android.material.button.MaterialButton
android:enabled="false"
..>
If you want to change the disabled color you can use a custom selector
<com.google.android.material.button.MaterialButton
app:backgroundTint="#color/my_selector"
..>
or you can override the colors used in the default selector:
<com.google.android.material.button.MaterialButton
android:theme="#style/button_overlay"
..>
with:
<style name="button_overlay">
<item name="colorOnSurface">#color/my_color</item>
</style>
Create a new Android Resource Directory inside your res folder. Give it the name "color" (see attached image).
Create a Color Resource File with the name "button_disabled" (see attached image).
Place the below code into the button_disabled.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="#FD7E14" android:alpha="0.45" />
<item android:color="#FD7E14" />
</selector>
Locate your values/styles.xml and add the below code
<style name="AppMaterialButton" parent="Widget.MaterialComponents.Button.UnelevatedButton"> <item name="android:backgroundTint">#color/button_disabled</item> </style>
Goto your layout/activity_filename.xml file and add this
android:enabled="false" to your button widget.
<com.google.android.material.button.MaterialButton
android:enabled="false"
android:id="#+id/button_Join"
style="#style/AppMaterialButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="next"
app:cornerRadius="0dp" />
Android Resource Directory
you should use a ThemeOverlay and apply the Colored style separately
<style name="AccentButton" parent="ThemeOverlay.AppCompat.Dark">
<!-- customize colorButtonNormal for the disable color -->
<!-- customize colorAccent for the enabled color -->
</style>
<Button
android:id="#+id/login_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/fragment_login_login_button"
android:theme="#style/AccentButton"
style="#style/Widget.AppCompat.Button.Colored"/>
Those looking to change icon and text color in button disabled state, here is how we can do steps are almost same for changing background color.
create a file inside color/button_enable_disable_state.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#android:color/white" android:state_enabled="true" />
<item android:alpha=".3" android:color="#android:color/white" />
</selector>
then go to your them or directly apply to your view like below.
<style name="ButtonStyled" parent="Widget.MaterialComponents.Button">
<item name="iconGravity">textStart</item>
<item name="iconPadding">12dp</item>
<item name="iconTint">#color/button_enable_disable_state</item>
<item name="android:textColor">#color/button_enable_disable_state</item>
</style>
and apply to your view if using theme like below
<com.google.android.material.button.MaterialButton
android:id="#+id/call_button"
style="#style/ButtonStyled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:layout_marginBottom="6dp"
android:enabled="false"
android:text="Call"
android:visibility="visible"
app:icon="#drawable/ic_call_icon"
/>
or directly apply apply to a view like below
<com.google.android.material.button.MaterialButton
android:id="#+id/call_button"
style="#style/ButtonStyled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:layout_marginBottom="6dp"
android:enabled="false"
android:text="Call"
android:visibility="visible"
android:textColor="#color/button_enable_disable_state"
app:iconTint="#color/button_enable_disable_state"
app:icon="#drawable/ic_call_icon"
/>
One of the best ways to create enable/disable effect is by overriding the MaterialButton class and apply ColorMatrix on it
import android.content.Context
import android.graphics.Canvas
import android.graphics.ColorMatrix
import android.graphics.ColorMatrixColorFilter
import android.graphics.Paint
import android.util.AttributeSet
import com.google.android.material.button.MaterialButton
class MaterialButtonCustom #JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
): MaterialButton(context,attrs,defStyleAttr) {
var disabled = false
set(value) {
field = value
requestLayout()
}
private val paint = Paint()
init {
val cm = ColorMatrix()
cm.set(
floatArrayOf(
0.6f, 0.6f, 0.6f, 0f, 0f,
0.6f, 0.6f, 0.6f, 0f, 0f,
0.6f, 0.6f, 0.6f, 0f, 0f,
0f, 0f, 0f, 1f, 0f
)
)
paint.colorFilter = ColorMatrixColorFilter(cm)
}
override fun dispatchDraw(canvas: Canvas?) {
if (disabled) {
canvas?.saveLayer(null, paint)
}
super.dispatchDraw(canvas)
if (disabled) {
canvas?.restore()
}
}
override fun draw(canvas: Canvas?) {
if (disabled) {
canvas?.saveLayer(null, paint)
}
super.draw(canvas)
if (disabled) {
canvas?.restore()
}
}
}
and inside Activity
class MainActivity : AppCompatActivity() {
lateinit var btn_plus:MaterialButtonCustom
var isActive: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn_plus = findViewById(R.id.btn_plus)
setBtnEnabled()
btn_plus.setOnClickListener {
isActive = !isActive
if(isActive){
setBtnDisabled()
}else{
setBtnEnabled()
}
}
}
private fun setBtnDisabled() {
btn_plus.disabled = true
}
private fun setBtnEnabled() {
btn_plus.disabled = false
}
}

Xamarin Forms: How to change text color of selected tab using TabbedPageRenderer

I am developing Tabs using TabbedPageRenderer. I am not able to change text color of selected tab(Only getting change selected tab icon color).
Below is MyTabbedPageRenderer.cs class
public class MyTabbedPageRenderer : TabbedPageRenderer
{
bool setup;
ViewPager pager;
TabLayout layout;
public MyTabbedPageRenderer(Context context) : base(context)
{ }
protected override void SetTabIcon(TabLayout.Tab tab, FileImageSource icon)
{
base.SetTabIcon(tab, icon);
tab.SetCustomView(Resource.Layout.Custom_tab_layou);
var imageview = tab.CustomView.FindViewById<ImageView>(Resource.Id.icon);
var tv = tab.CustomView.FindViewById<TextView>(Resource.Id.tv);
tv.SetText(tab.Text, TextView.BufferType.Normal);
imageview.SetBackgroundDrawable(tab.Icon);
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (setup)
return;
if (e.PropertyName == "Renderer")
{
pager = (ViewPager)ViewGroup.GetChildAt(0);
layout = (TabLayout)ViewGroup.GetChildAt(1);
setup = true;
ColorStateList colors = null;
//using xml file
if ((int)Build.VERSION.SdkInt >= 23)
colors = Resources.GetColorStateList(Resource.Color.icon_tab, Forms.Context.Theme);
else
colors = Resources.GetColorStateList(Resource.Color.icon_tab);
for (int i = 0; i < layout.TabCount; i++)
{
var tab = layout.GetTabAt(i);
var icon = tab.Icon;
Android.Views.View view = GetChildAt(i);
if (view is TabLayout)
layout = (TabLayout)view;
if (icon != null)
{
icon = Android.Support.V4.Graphics.Drawable.DrawableCompat.Wrap(icon);
Android.Support.V4.Graphics.Drawable.DrawableCompat.SetTintList(icon, colors);
}
}
}
}
}
This xml file applied for changing selected tab & text color
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:color="#E2725B"
android:state_selected="true" />
<item android:color="#FFFFFF" />
<item app:tabSelectedTextColor="#F3E5AB" />
</selector>
styles using for MainActivity
<style name="MainTheme" parent="MainTheme.Base">
</style>
<!-- Base theme applied no matter what API -->
<style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
style using for splashActivity
<style name="MyTheme.Splash" parent
="ThemeOverlay.AppCompat.Dark.ActionBar">
<item name="android:windowBackground">#drawable/splash</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
</style>
Tabbar.axml file below
<android.support.design.widget.TabLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:tabIndicatorColor="#BF94E4"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:tabSelectedTextColor="#DFFF00"
app:tabGravity="fill"
app:tabMode="fixed" />
Below screenshot of output where only icon color getting changed
Xamarin Forms: How to change text color of selected tab using TabbedPageRenderer
There is no need to use TabbedPageRenderer to change the selected tab text color, you can change it directly Via XML attributes.
In your Resource\layout\Tabbar.axml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.TabLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:tabMode="fixed"
app:tabGravity="fill"
app:tabTextColor="#color/your_unselected_text_color"
app:tabSelectedTextColor="#color/your_selected_text_color"
app:tabIndicatorColor="#color/your_indicator_color"
/>
Update:
Give your TextView a ColorStateList will solve this issue. In your MyTabbedPageRenderer SetTabIcon method:
protected override void SetTabIcon(TabLayout.Tab tab, FileImageSource icon)
{
base.SetTabIcon(tab, icon);
tab.SetCustomView(Resource.Layout.Custom_tab_layou);
var imageview = tab.CustomView.FindViewById<ImageView>(Resource.Id.icon);
var tv = tab.CustomView.FindViewById<TextView>(Resource.Id.tv);
tv.SetText(tab.Text, TextView.BufferType.Normal);
imageview.SetBackgroundDrawable(tab.Icon);
ColorStateList colors2 = null;
if ((int)Build.VERSION.SdkInt >= 23)
colors2 = Resources.GetColorStateList(Resource.Color.icon_tab, Forms.Context.Theme);
else
colors2 = Resources.GetColorStateList(Resource.Color.icon_tab);
tv.SetTextColor(colors2);
}
Effect.
See if this might helpful to you How to change selected Tab text color
you can use TabLayout instead like this:
<?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:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.design.widget.TabLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/tablayout"
app:tabTextColor="#color/colorPrimary"
app:tabSelectedTextColor="#color/colorAccent"
app:tabIndicatorColor="#android:color/holo_orange_light">
<android.support.design.widget.TabItem
android:text="tab 1"/>
<android.support.design.widget.TabItem
android:text="tab 2"/>
<android.support.design.widget.TabItem
android:text="tab 3"/>
</android.support.design.widget.TabLayout>
</LinearLayout>

Ripple effect using itemBackground on NavigationView

I wonder if anyone is having problems when redefining the background of the items on a NavigationView with app:itemBackground"? I get the behavior shown on the screenshot, no matter what item I press the last item shows the ripple instead.
Here is my drawer_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single" android:id="#+id/first_group">
<item
android:id="#+id/nav_home"
android:icon="#drawable/ic_home"
android:title="#string/nav_home" />
</group>
<group android:id="#+id/second_group">
<item
android:id="#+id/nav_settings"
android:title="#string/nav_settings" />
<item
android:id="#+id/nav_about"
android:title="#string/nav_about" />
<item
android:id="#+id/nav_logout"
android:title="#string/nav_logout" />
</group>
</menu>
My my_ripple.xml:
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#ffff0000">
<item
android:id="#android:id/mask"
android:drawable="#android:color/white" />
</ripple>
My NavigationView:
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#android:color/white"
app:headerLayout="#layout/drawer_header"
app:itemBackground="#drawable/my_ripple"
app:itemIconTint="#color/drawer_item"
app:itemTextColor="#color/drawer_item"
app:menu="#menu/drawer_menu" />
Possible workaround for now - Just for people looking and just in case....
Adding addOnGlobalLayoutListener in onCreate for the navigation view and applying the Drawable on each menu item.
/**
* Contains the {#link MenuItem} views in the {#link NavigationView}
*/
private final ArrayList<View> mMenuItems = new ArrayList<>(5);
// Grab the NavigationView Menu
final Menu navMenu = mNavigationView.getMenu();
mNavigationView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
// Remember to remove the installed OnGlobalLayoutListener
mNavigationView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
// Loop through and find each MenuItem View
for (int i = 0, length = 5; i < length; i++) {
final MenuItem item = navMenu.getItem(i);
mNavigationView.findViewsWithText(mMenuItems, item.getTitle(), View.FIND_VIEWS_WITH_TEXT);
}
// Loop through each MenuItem View and apply your custom Typeface
for (final View menuItem : mMenuItems) {
//Create RippleDrawable called myRipple
((TextView) menuItem).setBackground(myRipple);
}
}
});
Ripple drawables should be defined like this sample:
<!-- A red ripple masked against an opaque rectangle. -->
<ripple android:color="#ffff0000">
<item android:id="#android:id/mask"
android:drawable="#android:color/white" />
</ripple>
read more
https://developer.android.com/reference/android/graphics/drawable/RippleDrawable.html
Apply the itemBackground attribute to the menu rather than the NavigationView. The ripple will then stay contained to the menu item handling the touch event.

How to make custom dialog with rounded corners in android

What I am trying to do: I am trying to make a custom dialog in android With rounded corners.
What is happening: I am able to make custom dialog but it doesn't have rounded corners. I tried adding a selector but still I couldn't achieve rounded corners.
Below is my code for the same:
Java code:
private void launchDismissDlg() {
dialog = new Dialog(getActivity(), android.R.style.Theme_Dialog);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dlg_dismiss);
dialog.setCanceledOnTouchOutside(true);
Button btnReopenId = (Button) dialog.findViewById(R.id.btnReopenId);
Button btnCancelId = (Button) dialog.findViewById(R.id.btnCancelId);
btnReopenId.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
}
});
btnCancelId.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
}
});
dialog.setCanceledOnTouchOutside(false);
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
dialog.getWindow().setLayout(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);
dialog.show();
}
xml code:
<?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" >
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TableRow
android:id="#+id/tableRow1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text=""I WOULD LIKE TO DISMISS THE VENDOR""
android:textColor="#color/col_dlg_blue_light"
android:textSize="14sp"
android:textStyle="bold" />
</TableRow>
<TableRow
android:id="#+id/tableRow2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:gravity="center" >
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="BECAUSE"
android:textColor="#android:color/black"
android:textStyle="bold" />
</TableRow>
<TableRow
android:id="#+id/tableRow4"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="#+id/btnReopenId"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#color/col_dlg_green_light"
android:text="REOPEN"
android:padding="5dp"
android:textSize="14sp"
android:textColor="#android:color/white"
android:textStyle="bold" />
<Button
android:id="#+id/btnCancelId"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#color/col_dlg_pink_light"
android:text="CANCEL"
android:padding="5dp"
android:textSize="14sp"
android:textColor="#android:color/white"
android:textStyle="bold" />
</TableRow>
</TableLayout>
</LinearLayout>
Create an XML file in drawable, say dialog_bg.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="#color/white"/>
<corners
android:radius="30dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
set it as the background in your layout XML:
android:background="#drawable/dialog_bg"
Set the background of the dialog's root view to transparent, because Android puts your dialog layout within a root view that hides the corners in your custom layout.
Java:
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
Kotlin:
dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
With the Androidx library and Material Components Theme you can override the getTheme() method:
import androidx.fragment.app.DialogFragment
class RoundedDialog: DialogFragment() {
override fun getTheme() = R.style.RoundedCornersDialog
//....
}
with:
<style name="RoundedCornersDialog" parent="#style/Theme.MaterialComponents.Dialog">
<item name="dialogCornerRadius">16dp</item>
</style>
Or you can use the MaterialAlertDialogBuilder included in the Material Components Library:
import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
class RoundedAlertDialog : DialogFragment() {
//...
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return MaterialAlertDialogBuilder(requireActivity(), R.style.MaterialAlertDialog_rounded)
.setTitle("Test")
.setMessage("Message")
.setPositiveButton("OK", null)
.create()
}
}
with:
<style name="MaterialAlertDialog_rounded" parent="#style/ThemeOverlay.MaterialComponents.MaterialAlertDialog">
<item name="shapeAppearanceOverlay">#style/DialogCorners</item>
</style>
<style name="DialogCorners">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">16dp</item>
</style>
If you don't need a DialogFragment just use the MaterialAlertDialogBuilder.
You need to do the following:
Create a background with rounded corners for the Dialog's background:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#fff" />
<corners
android:bottomLeftRadius="8dp"
android:bottomRightRadius="8dp"
android:topLeftRadius="8dp"
android:topRightRadius="8dp" />
</shape>
Now in your Dialog's XML file in the root layout use that background with required margin:
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:background="#drawable/dialog_background"
finally in the java part you need to do this:
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(layoutResId);
View v = getWindow().getDecorView();
v.setBackgroundResource(android.R.color.transparent);
This works perfectly for me.
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
this works for me
Setting
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
will prevent dialog to cast a shadow.
Solution is to use
dialog.getWindow().setBackgroundDrawableResource(R.drawable.dialog_rounded_background);
where is R.drawable.dialog_rounded_background
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle" android:padding="10dp">
<solid
android:color="#color/dialog_bg_color"/>
<corners
android:radius="30dp" />
</shape>
</item>
</layer-list>
If you use Material Components:
CustomDialog.kt
class CustomDialog: DialogFragment() {
override fun getTheme() = R.style.RoundedCornersDialog
}
styles.xml
<style name="RoundedCornersDialog" parent="Theme.MaterialComponents.Dialog">
<item name="dialogCornerRadius">dimen</item>
</style>
dimen.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="weight">1</integer>
<dimen name="dialog_top_radius">21dp</dimen>
<dimen name="textview_dialog_head_min_height">50dp</dimen>
<dimen name="textview_dialog_drawable_padding">5dp</dimen>
<dimen name="button_dialog_layout_margin">3dp</dimen>
</resources>
styles.xml
<style name="TextView.Dialog">
<item name="android:paddingLeft">#dimen/dimen_size</item>
<item name="android:paddingRight">#dimen/dimen_size</item>
<item name="android:gravity">center_vertical</item>
<item name="android:textColor">#color/black</item>
</style>
<style name="TextView.Dialog.Head">
<item name="android:minHeight">#dimen/textview_dialog_head_min_height</item>
<item name="android:textColor">#color/white</item>
<item name="android:background">#drawable/dialog_title_style</item>
<item name="android:drawablePadding">#dimen/textview_dialog_drawable_padding</item>
</style>
<style name="TextView.Dialog.Text">
<item name="android:textAppearance">#style/Font.Medium.16</item>
</style>
<style name="Button" parent="Base.Widget.AppCompat.Button">
<item name="android:layout_height">#dimen/button_min_height</item>
<item name="android:layout_width">match_parent</item>
<item name="android:textColor">#color/white</item>
<item name="android:gravity">center</item>
<item name="android:textAppearance">#style/Font.Medium.20</item>
</style>
<style name="Button.Dialog">
<item name="android:layout_weight">#integer/weight</item>
<item name="android:layout_margin">#dimen/button_dialog_layout_margin</item>
</style>
<style name="Button.Dialog.Middle">
<item name="android:background">#drawable/button_primary_selector</item>
</style>
dialog_title_style.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="270"
android:endColor="#color/primaryDark"
android:startColor="#color/primaryDark" />
<corners
android:topLeftRadius="#dimen/dialog_top_radius"
android:topRightRadius="#dimen/dialog_top_radius" />
</shape>
dialog_background.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/backgroundDialog" />
<corners
android:topLeftRadius="#dimen/dialog_top_radius"
android:topRightRadius="#dimen/dialog_top_radius" />
<padding />
</shape>
dialog_one_button.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="wrap_content"
android:background="#drawable/dailog_background"
android:orientation="vertical">
<TextView
android:id="#+id/dialogOneButtonTitle"
style="#style/TextView.Dialog.Head"
android:text="Process Completed" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:orientation="vertical">
<TextView
android:id="#+id/dialogOneButtonText"
style="#style/TextView.Dialog.Text"
android:text="Return the main menu" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="#+id/dialogOneButtonOkButton"
style="#style/Button.Dialog.Middle"
android:text="Ok" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
OneButtonDialog.java
package com.example.sametoztoprak.concept.dialogs;
import android.app.Dialog;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import com.example.sametoztoprak.concept.R;
import com.example.sametoztoprak.concept.models.DialogFields;
/**
* Created by sametoztoprak on 26/09/2017.
*/
public class OneButtonDialog extends Dialog implements View.OnClickListener {
private static OneButtonDialog oneButtonDialog;
private static DialogFields dialogFields;
private Button dialogOneButtonOkButton;
private TextView dialogOneButtonText;
private TextView dialogOneButtonTitle;
public OneButtonDialog(AppCompatActivity activity) {
super(activity);
}
public static OneButtonDialog getInstance(AppCompatActivity activity, DialogFields dialogFields) {
OneButtonDialog.dialogFields = dialogFields;
return oneButtonDialog = (oneButtonDialog == null) ? new OneButtonDialog(activity) : oneButtonDialog;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.dialog_one_button);
getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialogOneButtonTitle = (TextView) findViewById(R.id.dialogOneButtonTitle);
dialogOneButtonText = (TextView) findViewById(R.id.dialogOneButtonText);
dialogOneButtonOkButton = (Button) findViewById(R.id.dialogOneButtonOkButton);
dialogOneButtonOkButton.setOnClickListener(this);
}
#Override
protected void onStart() {
super.onStart();
dialogOneButtonTitle.setText(dialogFields.getTitle());
dialogOneButtonText.setText(dialogFields.getText());
dialogOneButtonOkButton.setText(dialogFields.getOneButton());
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.dialogOneButtonOkButton:
break;
default:
break;
}
dismiss();
}
}
I made a new way without having a background drawable is that make it have CardView as parent and give it a app:cardCornerRadius="20dp" and then add this in the java class dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
It's another way to make it .
You can simply use MaterialAlertDialogBuilder to create custom dialog with rounded corners.
First create a style for the material dialog like this :
<style name="MyRounded.MaterialComponents.MaterialAlertDialog" parent="#style/ThemeOverlay.MaterialComponents.MaterialAlertDialog">
<item name="shapeAppearanceOverlay">#style/ShapeAppearanceOverlay.App.CustomDialog.Rounded
</item>
<item name="colorSurface">#color/YOUR_COLOR</item>
</style>
<style name="ShapeAppearanceOverlay.App.CustomDialog.Rounded" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">10dp</item>
</style>
then create a Alert Dialog object in Java class like this :
AlertDialog alertDialog = new MaterialAlertDialogBuilder(this,R.style.MyRounded_MaterialComponents_MaterialAlertDialog) // for fragment you can use getActivity() instead of this
.setView(R.layout.custom_layout) // custom layout is here
.show();
final EditText editText = alertDialog.findViewById(R.id.custom_layout_text); // access to text view of custom layout
Button btn = alertDialog.findViewById(R.id.custom_layout_btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "onClick: " + editText.getText().toString());
}
});
That's all you need to do.
For anyone who like do things in XML, specially in case where you are using Navigation architecture component actions in order to navigate to dialogs
You can use:
<style name="DialogStyle" parent="ThemeOverlay.MaterialComponents.Dialog.Alert">
<!-- dialog_background is drawable shape with corner radius -->
<item name="android:background">#drawable/dialog_background</item>
<item name="android:windowBackground">#android:color/transparent</item>
</style>
simplest way is to use from
CardView and its card:cardCornerRadius
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:id="#+id/cardlist_item"
android:layout_width="match_parent"
android:layout_height="130dp"
card:cardCornerRadius="40dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:background="#color/white">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="12sp"
android:orientation="vertical"
android:weightSum="1">
</RelativeLayout>
</android.support.v7.widget.CardView>
And when you are creating your Dialog
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
You can use the shape for the background as-
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#android:color/transparent"/>
<corners android:radius="10dp" />
<padding android:left="10dp" android:right="10dp"/>
</shape>
Have a look on this for the details.
Here is a Basic Solution:
<style name="Style_Dialog_Rounded_Corner" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:windowBackground">#drawable/dialog_rounded_corner</item>
<item name="android:windowMinWidthMinor">85%</item>
</style>
in Drawable create shape:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF" />
<corners android:radius="12dp" />
</shape>
Pass style in Builder Constructor
AlertDialog alert = new AlertDialog.Builder(MainActivity.this,R.style.Style_Dialog_Rounded_Corner).create();
Here is the complete solution if you want to control the corner radius of the dialog and preserve elevation shadow
Dialog:
class OptionsDialog: DialogFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle?): View {
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
return inflater.inflate(R.layout.dialog_options, container)
}
}
dialog_options.xml layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="40dp"
app:cardElevation="20dp"
app:cardCornerRadius="12dp">
<androidx.constraintlayout.widget.ConstraintLayout
id="#+id/actual_content_goes_here"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</FrameLayout>
The key is to wrap the CardView with another ViewGroup (here FrameLayout) and set margins to create space for the elevation shadow.
For API level >= 28 available attribute android:dialogCornerRadius . To support previous API versions need use
<style name="RoundedDialog" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:windowBackground">#drawable/dialog_bg</item>
</style>
where dialog_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item >
<shape >
<solid android:color="#android:color/transparent" />
</shape>
</item>
<item
android:left="16dp"
android:right="16dp">
<shape>
<solid
android:color="#color/white"/>
<corners
android:radius="8dp" />
<padding
android:left="16dp"
android:right="16dp" />
</shape>
</item>
</layer-list>
In Kotlin, I am using a class DoubleButtonDialog.Java with line window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) as important one
class DoubleButtonDialog(context: Context) : Dialog(context, R.style.DialogTheme) {
private var cancelableDialog: Boolean = true
private var titleDialog: String? = null
private var messageDialog: String? = null
private var leftButtonDialog: String = "Yes"
// private var rightButtonDialog: String? = null
private var onClickListenerDialog: OnClickListener? = null
override fun onCreate(savedInstanceState: Bundle?) {
window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
//requestWindowFeature(android.view.Window.FEATURE_NO_TITLE)
setCancelable(cancelableDialog)
setContentView(R.layout.dialog_double_button)
// val btnNegative = findViewById<Button>(R.id.btnNegative)
// btnNegative.visibility = View.GONE
// if (rightButtonDialog != null) {
// btnNegative.visibility = View.VISIBLE
// btnNegative.text = rightButtonDialog
// btnNegative.setOnClickListener {
// dismiss()
// onClickListenerDialog?.onClickCancel()
// }
// }
val btnPositive = findViewById<Button>(R.id.btnPositive)
btnPositive.text = leftButtonDialog
btnPositive.setOnClickListener {
onClickListenerDialog?.onClick()
dismiss()
}
(findViewById<TextView>(R.id.title)).text = titleDialog
(findViewById<TextView>(R.id.message)).text = messageDialog
super.onCreate(savedInstanceState)
}
constructor(
context: Context, cancelableDialog: Boolean, titleDialog: String?,
messageDialog: String, leftButtonDialog: String, /*rightButtonDialog: String?,*/
onClickListenerDialog: OnClickListener
) : this(context) {
this.cancelableDialog = cancelableDialog
this.titleDialog = titleDialog
this.messageDialog = messageDialog
this.leftButtonDialog = leftButtonDialog
// this.rightButtonDialog = rightButtonDialog
this.onClickListenerDialog = onClickListenerDialog
}
}
interface OnClickListener {
// fun onClickCancel()
fun onClick()
}
In layout, we can create a dialog_double_button.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="#dimen/dimen_10"
android:background="#drawable/bg_double_button"
android:orientation="vertical"
android:padding="#dimen/dimen_5">
<TextView
android:id="#+id/title"
style="#style/TextViewStyle"
android:layout_gravity="center_horizontal"
android:layout_margin="#dimen/dimen_10"
android:fontFamily="#font/campton_semi_bold"
android:textColor="#color/red_dark4"
android:textSize="#dimen/text_size_24"
tools:text="#string/dial" />
<TextView
android:id="#+id/message"
style="#style/TextViewStyle"
android:layout_gravity="center_horizontal"
android:layout_margin="#dimen/dimen_10"
android:gravity="center"
android:textColor="#color/semi_gray_2"
tools:text="#string/diling_police_number" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/dimen_10"
android:gravity="center"
android:orientation="horizontal"
android:padding="#dimen/dimen_5">
<!--<Button
android:id="#+id/btnNegative"
style="#style/ButtonStyle"
android:layout_width="0dp"
android:layout_height="#dimen/dimen_40"
android:layout_marginEnd="#dimen/dimen_10"
android:layout_weight=".4"
android:text="#string/cancel" />-->
<Button
android:id="#+id/btnPositive"
style="#style/ButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#color/red_dark4"
android:fontFamily="#font/campton_semi_bold"
android:padding="#dimen/dimen_10"
android:text="#string/proceed"
android:textAllCaps="false"
android:textColor="#color/white"
android:textSize="#dimen/text_size_20" />
</LinearLayout>
</LinearLayout>
then use drawable.xml as
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="#color/white"/>
<corners
android:radius="#dimen/dimen_10" />
<padding
android:left="#dimen/dimen_10"
android:top="#dimen/dimen_10"
android:right="#dimen/dimen_10"
android:bottom="#dimen/dimen_10" />
</shape>
Create a xml in drawable ,say customd.xml.
then set it at background in your custom Dialog layout xml:
android:background="#drawable/customd"
finally in the java part for custom Dialog class you need to do this:
public class Customdialoque extends DialogFragment {
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
View view = inflater.inflate(R.layout.activity_customdialoque, container, false);
return view;
}
I implemented rounded dialog using CardView in the custom layout and setting its corner radius.
Here's my xml code.
<?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:id="#+id/bottomSheet"
android:layout_width="match_parent"
android:layout_margin="#dimen/padding_5dp"
app:cardCornerRadius="#dimen/dimen_20dp"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/main_gradient_bg"
android:paddingBottom="32dp">
<TextView
android:id="#+id/subdomain_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/margin_32dp"
android:layout_marginLeft="#dimen/margin_32dp"
android:layout_marginTop="#dimen/margin_50dp"
android:fontFamily="#font/nunito_sans"
android:text="#string/enter_subdomain"
android:textColor="#color/white"
android:textSize="#dimen/size_18sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/dimen_45dp"
app:layout_constraintLeft_toRightOf="#id/subdomain_label"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_baseline_info_24" />
<EditText
android:id="#+id/subdomain_edit_text_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/dimen_20dp"
android:layout_marginLeft="#dimen/dimen_20dp"
android:layout_marginEnd="#dimen/dimen_20dp"
android:layout_marginRight="#dimen/dimen_20dp"
android:textColor="#color/white"
android:theme="#style/EditTextTheme"
app:layout_constraintTop_toBottomOf="#id/subdomain_label" />
<Button
android:id="#+id/proceed_btn"
android:layout_width="#dimen/dimen_150dp"
android:layout_height="#dimen/margin_50dp"
android:layout_marginTop="#dimen/margin_30dp"
android:background="#drawable/primary_btn_bg"
android:text="#string/proceed"
android:textAllCaps="false"
android:textColor="#color/white"
android:textSize="#dimen/size_18sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/subdomain_edit_text_bottom_sheet" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
After that, i called it in Kotlin as follows :-
val builder = AlertDialog.Builder(mContext)
val viewGroup: ViewGroup = findViewById(android.R.id.content)
val dialogView: View =
LayoutInflater.from(mContext).inflate(R.layout.subdomain_bottom_sheet,
viewGroup, false)
val alertDialog: AlertDialog = builder.create()
alertDialog.setView(dialogView,0,0,0,0)
alertDialog.show()
val windowParam = WindowManager.LayoutParams()
windowParam.copyFrom(alertDialog.window!!.attributes)
windowParam.width = AppConstant.getDisplayMetricsWidth(mContext) - 100
windowParam.height = WindowManager.LayoutParams.WRAP_CONTENT
windowParam.gravity = Gravity.CENTER
alertDialog.window!!.attributes = windowParam
alertDialog.window!!.setBackgroundDrawable
(ColorDrawable(Color.TRANSPARENT))
Where last line is very important. Missing that would cause a color(mostly white) to show behind the corners.
The accepted answer did round the corners for me, but unless I switched to a Material design theme, making the window background transparent had no effect and I still saw a square, shadowed background of the dialog inside my rounded background. And I don't want to switch to a Material theme because that changes the functionality of date and time pickers.
Instead, I had to hide the backgrounds of several subviews of the dialog in order to see the rounded background. And after doing all that, it was easier just to add the rounded background in code, too. So here's a fully programmatic (no XML) solution. This is in the onStart method of my DialogFragment subclass:
// add rounded corners
val backgroundShape = GradientDrawable()
backgroundShape.cornerRadius = 10.0f
backgroundShape.setColor(Color.BLUE)
this.dialog.window?.decorView?.background = backgroundShape
// make the backgrounds of the dialog elements transparent so we can see the rounded corner background
val topPanelId = this.context.resources.getIdentifier("topPanel", "id", "android")
val topPanel = this.dialog.findViewById<View>(topPanelId)
topPanel?.setBackgroundColor(Color.TRANSPARENT)
val contentPanelId = this.context.resources.getIdentifier("contentPanel", "id", "android")
val contentPanel = this.dialog.findViewById<View>(contentPanelId)
contentPanel?.setBackgroundColor(Color.TRANSPARENT)
val customPanelId = this.context.resources.getIdentifier("customPanel", "id", "android")
val customPanel = this.dialog.findViewById<View>(customPanelId)
customPanel?.setBackgroundColor(Color.TRANSPARENT)
val buttonPanelId = this.context.resources.getIdentifier("buttonPanel", "id", "android")
val buttonPanel = this.dialog.findViewById<View>(buttonPanelId)
buttonPanel?.setBackgroundColor(Color.TRANSPARENT)
Here is another way in kotlin:
val model = ShapeAppearanceModel()
.toBuilder()
.setAllCorners(CornerFamily.ROUNDED, 32.0f)
.build()
val shape = MaterialShapeDrawable(model)
shape.fillColor = ContextCompat.getColorStateList(context, R.color.white)
ViewCompat.setBackground(dialogContentView, shape)
And then change the dialog window
dialog?.window?.setBackgroundDrawableResource(android.R.color.transparent)

Categories

Resources