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:
Related
I'm trying to add an icon to a switch control via thumbIcon, but I can't find a way to resize the icon. I'm trying to learn about this on this Page but I haven't been able to.
If I use the drawable without a selector, the icon displays the correct size, but if I use the drawable with the selector, the icon size becomes large, larger than 16dp and unsightly. Is there a way to change the icon size with the drawable mode selector? or can this be done in some way? I want when the switch is in the unchecked position it shows a different icon than the checked position with the right size or fit.
Material Switch
<com.google.android.material.materialswitch.MaterialSwitch
android:id="#+id/SFilter_WorldWideValue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:checked="true"
android:fontFamily="#font/roboto_medium"
android:text="#string/search"
android:textAllCaps="true"
android:textColor="#color/Text_Base_White"
android:textIsSelectable="false"
android:textSize="16sp"
app:thumbIcon="#drawable/icon_check" --> **Normal Size**
app:thumbIcon="#drawable/default_switch_icon" --> **Size is not normal**
tools:ignore="TouchTargetSizeCheck" />
style.xml
<style name="Theme.Default" parent="Theme.Material3.Light.NoActionBar">
...
<item name="materialSwitchStyle">#style/Switch.Default</item>
</style>
<style name="Switch.Default" parent="Widget.Material3.CompoundButton.MaterialSwitch">
<item name="thumbIcon">#drawable/default_switch_icon</item>
<item name="checkedIconSize">16dp</item> // Not working
<item name="selectorSize">16dp</item> // Not working
<item name="iconSize">16dp</item> // Not working
<item name="drawableSize">16dp</item> // Not working
<item name="itemIconSize">16dp</item> // Not working
<item name="maxImageSize">16dp</item> // Not working
<item name="materialThemeOverlay">#style/Switch.Colors.Default</item>
</style>
<style name="Switch.Colors.Default" parent="">
...
...
</style>
drawable/default_switch_icon.xml
<?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:state_checked="true"
android:drawable="#drawable/icon_check"/>
<item
android:state_checked="false"
android:drawable="#drawable/icon_close"/>
</selector>
You can use a layer-list in your selector :
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- State Checked -->
<item android:state_checked="true">
<layer-list>
<item android:drawable="#drawable/ic_check"
android:height="16dp"
android:width="16dp"
android:gravity="center"/>
</layer-list>
</item>
<!-- State Unchecked -->
<item android:drawable="#color/transparent" />
</selector>
I had to set the gravity to center or the icon was not centered in the thumb.
This question already has answers here:
Issue: change border color or box stroke for unfocused TextInputLayout in android
(4 answers)
Closed 2 years ago.
I am trying to setting up TextInputLayout unfocused border stroke color. For the same, There are too many questions and their answers and I have tried all of them. Like Created styles and used as theme, Created color selector and applied that, and also applied directly app:boxStrokeColor with color selector. But not luck with any of these available solutions.
Not sure, where do i am doing wrong or something i still missing. I pushed my code to Test project to github for to get better visibility of my whole setup. Here is some sample code for quick review:
activity_main.xml (TextInputLayout inside ConstraintLayout)
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- Tried this as well - app:boxStrokeColor="#color/text_input_box_stroke_color" -->
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/emailTextInputLayout"
android:hint="Email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:theme="#style/TextInputLayoutStyle"
android:layout_marginHorizontal="24dp"
app:layout_constraintTop_toBottomOf="#id/toolbar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/emailTextInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:importantForAutofill="no"
android:inputType="textEmailAddress" />
</com.google.android.material.textfield.TextInputLayout>
styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="TextInputLayoutStyle" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense">
<item name="boxStrokeColor">#FF00CC</item>
<item name="boxStrokeWidth">2dp</item>
</style>
</resources>
text_input_box_stroke_color.xml (color selector)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/mtrl_textinput_focused_box_stroke_color" android:state_focused="true"/>
<item android:color="#color/mtrl_textinput_hovered_box_stroke_color" android:state_hovered="true"/>
<item android:color="#color/mtrl_textinput_disabled_color" android:state_enabled="false"/>
<item android:color="#color/mtrl_textinput_default_box_stroke_color"/>
</selector>
It would be great help if someone can provide some guideline and suggestion and help me figure out any mistake made by me.
Thanks in advance.
I have tested your code and it works after you do the below changes:
1.First change your res/color/text_input_box_stroke_color.xml like below to see the different states colors. In the below example i have set a Red color for the focused state and a Light Blue color for default-inactive state:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#android:color/holo_red_dark" android:state_focused="true" />
<item android:color="#android:color/holo_green_dark" android:state_hovered="true" />
<item android:color="#color/mtrl_textinput_disabled_color" android:state_enabled="false" />
<item android:color="#android:color/holo_blue_light" />
</selector>
2.Then change your res/values/styles.xml with the boxStrokeColor linking to the above selector like below:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="TextInputLayoutStyle" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense">
<item name="boxStrokeColor">#color/text_input_box_stroke_color</item>
<item name="boxStrokeWidth">2dp</item>
</style>
</resources>
3.Finally in your TextInputLayout add this style like below:
<com.google.android.material.textfield.TextInputLayout
style="#style/TextInputLayoutStyle"
android:id="#+id/emailTextInputLayout"
Currently your adding the style like: android:theme="#style/TextInputLayoutStyle" instead of style="#style/TextInputLayoutStyle"
Solution for this is next, and this works because I JUST NOW tested it.
Go to your colors.xml inside your res>values folder.
In there you'll have your colorPrimary and other colors you already created before. Scroll to the bottom and add this line:
<color name="mtrl_textinput_default_box_stroke_color" tools:override="true">#color/colorPrimary</color>
When you do that, you can just change the color there. I defined as #color/colorPrimary but you can use whatever you want. Before applying this line I got this:
And after applying that line this is the result:
Also I applied style="#style/YourStyle" for both TextInputLayout and TextInputEditText
Create a box stroke color for active and inactive state like below:
box_stroke_color
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#2C2C2C" android:state_focused="true"/>
<item android:color="#2C2C2C" android:state_hovered="true"/>
<item android:color="#D7D7D7"/>
</selector>
Make a TextInputLayout style : TextInputLayoutStyle
<style name="TextInputLayoutStyle" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<item name="boxStrokeColor">#color/box_stroke_color</item>
<item name="boxStrokeWidth">1dp</item>
</style>
Use in your TextInputLayout
<com.google.android.material.textfield.TextInputLayout
style="#style/TextInputLayoutStyle" >
<com.google.android.material.textfield.TextInputEditText.. />
</com.google.android.material.textfield.TextInputLayout>
I have always had trouble with Android selectors, and I can't understand how to make this work.
I have a button called "Completed" which is grey and disabled until you have indeed completed everything you need to, then it turns blue. There's no problem doing this programmatically, however I feel like using an xml drawable is more appropriate. The point is that if I use it, the button is blue until I don't set it enabled(false) (as if it's choosing the last option in the drawable file), and then it doesn't change its appearance, even though I set it enabled(true) (and it is indeed enabled).
If I use android:theme instead of style, the button doesn't have any of my appearances (it is light grey, something I never set) until I set it disabled (and then doesn't change appearance).
This is my button:
<Button
android:id="#+id/completed"
style="#style/MyButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="#dimen/half_spacing"
android:layout_marginEnd="#dimen/default_spacing"
android:layout_marginLeft="#dimen/default_spacing"
android:layout_marginRight="#dimen/default_spacing"
android:layout_marginStart="#dimen/default_spacing"
android:layout_marginTop="#dimen/default_spacing"
android:enabled="true"
android:gravity="center"
android:paddingTop="#dimen/half_spacing"
android:text="#string/completed"/>
This is my styles.xml:
<style name="MyButton" parent="Widget.AppCompat.Button">
<item name="android:background">#drawable/my_button</item>
<item name="android:textColor">#color/white</item>
<item name="android:textStyle">bold</item>
<item name="android:paddingBottom">#dimen/half_spacing</item>
<item name="android:paddingLeft">#dimen/default_spacing</item>
<item name="android:paddingRight">#dimen/default_spacing</item>
<item name="android:paddingTop">#dimen/half_spacing</item>
</style>
My drawable:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/my_button_enabled"
android:state_enabled="true"/>
<item android:drawable="#drawable/my_button_disabled"
android:state_enabled="false"/>
<item android:drawable="#drawable/my_button_enabled"/>
</selector>
Drawable for button enabled:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/colorPrimaryDark"
android:state_pressed="true"/>
<item android:drawable="#color/colorAccent"/>
</selector>
Drawable for button disabled:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/dark_grey"
android:state_pressed="true"/>
<item android:drawable="#color/grey"/>
</selector>
The code (as you can see, I have commented the part where I set the background dynamically):
if (mCurrentPosition == mCurrentDocument.getDocumentSections().size() - 1) {
mCompleted.setEnabled(true);
// mCompleted.setBackgroundColor(ContextCompat.getColor(MainActivity.this, R.color.colorAccent));
} else {
mCompleted.setEnabled(false);
// mCompleted.setBackgroundColor(ContextCompat.getColor(MainActivity.this, R.color.grey));
}
I have tried pretty much everything I could find, I am really out of ideas.
Thanks in advance!
I have the following style in my styles.xml that a toggle button is using. However, i want the toggle button to fill_parent but not stretch the image. How can i tell it to center this background image and not stretch it? I'm trying to increase the area the user can click on.
Toggle:
<ToggleButton
android:id="#+id/OtherToggle"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
style="#style/OtherToggle" />
Style:
<style name="OtherToggle">
<item name="android:textOn">""</item>
<item name="android:textOff">""</item>
<item name="android:disabledAlpha">?android:attr/disabledAlpha</item>
<item name="android:background">#drawable/other_toggle_bg</item>
</style>
I assume you mean that you do want to stretch the image, but you want to keep the aspect ratio unchanged?
If so, try adding this to your style:
<item name="android:scaleType">centerInside</item>
See here for the other possibilities if centerInside does not do what you want.
Maybe you can use layer-list as a background drawable for ToggleButton? Create the following xml file and use it in android:background attribute:
<?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>
<bitmap android:src="#drawable/other_toggle_bg"
android:gravity="center" />
</item>
</layer-list>
Recently my ToggleButtons on an application I'm working on lost it's green light indicator. I started with the various tutorials and got together a set of 9 patch indicators to make them work correctly again. The only problem is the text now sits on top of the indicator, like so:
I would like the text on top like the old toggle buttons...is there any way to do this?
btn_toggle_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:drawable/btn_default" />
<item android:id="#+android:id/toggle" android:drawable="#drawable/btn_toggle" />
</layer-list>
my btn_toggle.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="#drawable/btn_toggle_on" />
<item android:state_checked="false" android:drawable="#drawable/btn_toggle_off" />
</selector>
and the togglebutton tag in my activity:
<ToggleButton
android:background="#drawable/btn_toggle_bg"
style="#style/OurThemeName"
android:textOff="#string/fertilizer"
android:textOn="#string/fertilizer"
android:id="#+id/toggleFertilizer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="false">
</ToggleButton>
<ToggleButton
android:background="#drawable/btn_toggle_bg"
style="#style/OurThemeName"
android:textOff="#string/irrigation"
android:textOn="#string/irrigation"
android:id="#+id/toggleIrrigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="false">
</ToggleButton>
almost forgot the themes.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Overwrite the ToggleButton style -->
<style name="Widget.Button.Toggle" parent="android:Widget">
<item name="android:background">#drawable/btn_toggle_bg</item>
<item name="android:textOn">On</item>
<item name="android:textOff">Off</item>
<item name="android:disabledAlpha">?android:attr/disabledAlpha</item>
</style>
<style name="OurThemeName" parent="#android:Theme.Light">
<item name="android:buttonStyleToggle">#style/Widget.Button.Toggle</item>
<item name="android:textOn"></item>
<item name="android:textOff"></item>
</style>
</resources>
You need to set the Fill Area in your 9-Patch. You can add this areas including them in the right and bottom of your images using the Draw 9-patch tool. With this you are defining the area for your text label.
Check this tutorial explaining how 9-Patch works.