I have a little problem designing a button for my Android app. I have created a button with 3D effect like the one shown in the following image:
But, if you have noticed, when the button is pressed, the text does not move with the rest of the elements down, but it stays in the same place and this causes the button effect to be lost. It should look like the image below:
Does anyone have an idea how to fix this?
This is my code:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
tools:context=".MainActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/WelcomeImage"
android:src="@drawable/logo"
android:layout_marginTop="108dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<Button
android:id="@+id/btStart"
android:layout_width="300dp"
android:layout_height="50dp"
android:text="Start"
android:background="@drawable/button3d"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="32dp" />
</RelativeLayout>
This is the code for the 3D effect of the button:
button3d.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false">
<layer-list>
<item>
<shape>
<solid android:color="#A6A6A6" />
<corners android:radius="7.0dip" />
</shape>
</item>
<item android:bottom="4.0dip">
<shape>
<corners android:radius="7.0dip" />
<solid android:color="@android:color/white" />
</shape>
</item>
</layer-list>
</item>
<item android:state_pressed="true">
<layer-list>
<item>
<shape >
<padding android:top="4.0dip" />
<solid android:color="@android:color/transparent" />
</shape>
</item>
<item>
<shape>
<corners android:radius="7.0dip" />
<solid android:color="@android:color/white" />
</shape>
</item>
</layer-list>
</item>
</selector>
Thanks in advance.
UPDATE:
x4mp73r 's answer is a real wonder, but I found some bugs that it would be good for you to know, even x4mp73r.
The first one appears when you have implemented the function setOnTouchListener()
, because when you click on the button, the text effect appears correctly, but when you drag your finger away from the screen, without releasing your finger from the screen, it returns to its normal state and the text continues with the padding
one that touches it because you are still touching the screen. It's messy to explain and I can't show it to you with images, but if someone uses this, try pressing the button and without releasing it, drag your finger away from the button and it will be perfectly understood.
A simple solution was to split the file code button3d.xml
into two and make the OnTouch
button method handle the change of the padding
and background
the like this:
button3d_normal.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<layer-list>
<item>
<shape>
<solid android:color="#A6A6A6" />
<corners android:radius="7.0dip" />
</shape>
</item>
<item android:bottom="4.0dip">
<shape>
<corners android:radius="7.0dip" />
<solid android:color="@android:color/white" />
</shape>
</item>
</layer-list>
</item>
</selector>
button3d_pressed.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<layer-list>
<item>
<shape>
<padding android:top="4.0dip" />
<solid android:color="@android:color/transparent" />
</shape>
</item>
<item>
<shape>
<corners android:radius="7.0dip" />
<solid android:color="@android:color/white" />
</shape>
</item>
</layer-list>
</item>
</selector>
activity_main.xml
I would only change the button:
<Button
android:id="@+id/btStart"
android:layout_width="300dp"
android:layout_height="50dp"
android:text="@string/startIntro"
android:textColor="@color/colorPrimary"
android:textSize="22sp"
android:paddingBottom="5dp"
android:textAllCaps="false"
android:background="@drawable/button3d_normal"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="32dp" />
MainActivity.java
btStart = (Button) findViewById(R.id.btStart);
btStart.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
btStart.setBackground(ContextCompat.getDrawable(getApplicationContext(), R.drawable.button3d_pressed));
btStart.setPadding(0, px, 0, 0);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
btStart.setBackground(ContextCompat.getDrawable(getApplicationContext(), R.drawable.button3d_normal));
btStart.setPadding(0, 0, 0, px);
}
return false;
}
});
The last problem was that if I implemented the views OnTouchListener
and OnClickListener
in the class and assigned both to a button (in the same order), setOnClickListener
it didn't work for me.
The solution gave me head but it was very simple. The method onTouch
returns a boolean value, if we return that value as true
, it will mean that we have already finished with any action of this button and that nothing else will be implemented, but if we return false
it will be the opposite and we can continue applying more functions to it button.
I hope it will help you all, these buttons look great in an application.
I think there are many solutions, one of them is to make use of
setPadding
youronTouchListener
button:The padding can be more or less like this:
Another option is trying to add this property to your button:
O well:
I hope it is useful to you.