I'm trying to make a custom button style with a 3d look to it, but I'm having issue with the "pressed" state of the button. The button changes image properly, but the text stays still, which makes it look like the text is actually sliding upwards on press.
(Red lines added to show the cancel button's baseline)
XML for the button view (cmdNegative is the cancel button, layDialogControl is a layout directly above the buttons)
<Button
android:id="#+id/cmdPositive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/button_positive"
android:text="Accept"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintTop_toBottomOf="#+id/layDialogControl"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/cmdNegative"
app:layout_constraintBottom_toBottomOf="parent" />
XML for the button style (button_gray is the exact same as button_green just... well... gray)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_enabled="false"
android:drawable="#drawable/button_gray" />
<item
android:state_pressed="true"
android:state_enabled="true"
android:drawable="#drawable/button_green_pressed" />
<item
android:state_focused="true"
android:state_enabled="true"
android:drawable="#drawable/button_green_pressed" />
<item
android:state_enabled="true"
android:drawable="#drawable/button_green" />
</selector>
Unpressed 9 patch:
Pressed 9 patch:
As far as I'm understanding, setting the pixels on the right/bottom should have defined the "content area" and the text should stay in the content view, buuuuuuut that's not the case. Any ideas or pointers as to where I've messed up would be greatly appreciated.
I think you have misunderstood 9-patch images. The stretchable areas (top and left sides) that you define will stretch according to your layout definition. The content area, right and bottom parts defined will set the limits for your content similar to like specifying a rectangle/square of area where your content will be kept. Your image for the accept button(pressed) will not stretch when clicked, thus whatever your image looks like is showing.
Furthermore, if your image has the text in it then there is no point of having a content area. If your button image has text defined then you can solve your problem by re-defining your content area. In other words on the pressed-state you are just substituting an image which had the correct content area region so it looks like it has been stretched on click but it is actually just another image.
Related
I am trying to align android switchcompat on both side whether its checked or unchecked but without success.
<android.support.v7.widget.SwitchCompat
android:id="#+id/switch1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:checked="true"
android:clickable="true"
android:layout_gravity="center_vertical"/>
and here is the result
Any ideas how to get it done?
The Switches (the view bounds of switches to be specific) in your image are aligned as expected. However, it appears as though they are not aligned because the thumb actually goes a little out of the switch track (still within the view bounds). If you want the thumb and track to be aligned on both sides, you can create a custom Switch.
An example would be:
Create background.xml as follows:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"
android:drawable="#drawable/drawable1" />
<item android:state_checked="false" android:drawable="#drawable/drawable2"/>
</selector>
Set this as background for Switch:
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/background"/>
You will get something like:
I know this aint perfect in terms of design, but you get the idea!
This shows that the view bounds are actually aligned in both checked and unchecked states.
You can customize it further by setting the track, thumb and so on...
On tweaking the background a little and setting the track you can get something like:
Cheers!
How can I make a button with this theme? Blue and glowing box:
This can be done by creating a 9-patch image based on that custom button image (and optionally for the selected / pushed button state graphics). The 9-patch format is basically a PNG file with special marker pixels that slice the button graphic into segments so it can dynamically grow and shrink according to the final size of the button view. The Android SDK comes with a tool for creating those 9-patch images.
When this is done you need to create a state list XML resource file in the drawable resource directory. That state list references those 9-patch images for each button state (normal, pressed, etc.). The SDK documentation explains it nicely here: http://developer.android.com/guide/topics/ui/controls/button.html#CustomBackground
Code excerpt from that page:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/button_pressed"
android:state_pressed="true" />
<item android:drawable="#drawable/button_focused"
android:state_focused="true" />
<item android:drawable="#drawable/button_default" />
</selector>
In the end you can assign that XML drawable to your button as a background image resource like as follows:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Some label text"
android:background="#drawable/my_button_state_list" />
Is this possible? I have for example simple linearLayout with selector to create "click effect":
<LinearLayout
android:id="#+id/clickToChangeColor"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#color/click_effect" />
This is selector click_effect:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/pressed" android:state_enabled="true" android:state_pressed="true"/>
<item android:drawable="#drawable/unpressed" android:state_enabled="false"/>
</selector>
Everything works just fine, but when I press on this layout, I would like to launch activity (like color picker - but it doesn't matter) and then change color of linearlayout for example to blue. BUT: keep selector "click effect". Trying to do this almost for 2 hours, but nothing works...
PS: I know it can be done for example with another layout inside this layout, apply some padding and apply selector to outer layout and then I can change background of inner layout etc - but it's only ugly workaround
<ImageView
android:id="#+id/imageViewSelectedColor"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#color/click_effect"
android:src="#color/picked color" />
Use an image view instead now you can change src according to picked color.
How do I style an image button so that it displays as a PNG icon but on click/touch, the PNG shape gets a soft glowing edge?
You probably want to look at 9-patch
Basically you create a transparent png with the glow effect baked into the image, and it'll scale the edges while keeping the corners intact and letting you place the content within a predefined area of the image.
To map your images to a button, you need a selector, which is a xml file and goes into your projects drawables. A sample grabbed from another answer looks like this
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/red_button_pressed" />
<item android:state_focused="true" android:drawable="#drawable/red_button_focus" />
<item android:drawable="#drawable/red_button_rest" />
</selector>
I had a simple button set up with a background image defined like
android:background="?attr/button"
where ?attr/button was a reference to a simple 9-patch png. Everything worked fine, text in the button was aligned correctly.
Then I needed to have a different background for a pressed state of the button. So I changed that to
android:background="#drawable/state_button"
where #drawable/state_button is an xml with the following states
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#drawable/button_pressed" /> <!-- pressed -->
<item android:state_focused="true"
android:drawable="#drawable/button_pressed" /> <!-- focused -->
<item android:drawable="#drawable/button" /> <!-- default -->
</selector>
And after that I can't align the text properly. If I put android:gravity="center_vertical" the text is drawn about 1/4 of the button height from the top.
I double-checked my 9-patch images, everything seems fine with them. And I also tried having regular pngs for the background, it also doesn't change anything.
You should double check the 9 patch drawables you're using. The standard Android buttons include a huge amount of padding at the top and bottom of the buttons, making it look like the text is always centered. You can see this by opening up the 9 patch file, zooming in closely and looking at the difference between the pixels on the left/top and the right/bottom. The left/top sides mark which parts of the image can be stretched to accomodate more text, while the right/bottom sides mark the space that will actually be filled with text. So the difference between the right/bottom side and the left/top will be the padding. It doesn't quite make sense at first, but after playing around with it it's not so bad.
Just in case you aren't familiar with it, a useful tool for editing 9patches is the draw9patch.bat program in your SDK tools folder.
I had the exact same issue however my 9 patch drawables were ok. The cause was still the same though, just i was using custom drawables using the layer-list element.
It seems that when the Button lays out its text it takes into account all of the states in your selector. Once i'd updated all of the states to match each other my text subsequently aligned correctly.