In Android, when I set background image to Button, I can not see any effect on button.
I need some effect on button so user can recognize that button is clicked.
Button should be dark while a few second when it clicked, so what should I do for this?
Thanks.
This question is related to
android
Create your AlphaAnimation
Object that decides how much will be the fading effect of the button, then let it start in the onClickListener
of your buttons
For example :
private AlphaAnimation buttonClick = new AlphaAnimation(1F, 0.8F);
// some code
public void onClick(View v) {
v.startAnimation(buttonClick);
}
of course this is just a way, not the most preferred one, it's just easier
To make your item consistent with the system look and feel try referencing the system attribute android:attr/selectableItemBackground
in your desired view's background or foreground tag:
<ImageView
...
android:background="?android:attr/selectableItemBackground"
android:foreground="?android:attr/selectableItemBackground"
...
/>
Use both attributes to get desired effect before/after API level 23 respectively.
Use RippleDrawable for Material Design state pressed/clicked effect.
In order to achieve this, create ripple item as an .xml under /drawable folder and use it in android:background for any views.
Effect for icon pressed/clicked, use circular ripple effect, for example:
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@android:color/darker_gray"
/>
Effect for view clicked with rectangle boundary, we can add ripple over the existing drawable like bellow:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#000000">
<item android:drawable="@drawable/your_background_drawable"/>
</ripple>
just wanna add another easy way to do this: If your ImageButton remains its background and you don't set it to null, it will work like a normal button and will show the click animation while clicking exactly like other buttons.The way to hide the background while it is still there:
<ImageButton
android:id="@+id/imageButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="1dp"
android:paddingLeft="1dp"
android:paddingRight="1dp"
android:paddingTop="1dp"
android:src="@drawable/squareicon" />
The paddings won't let the background be visible and make the button act like other buttons.
It is simpler when you have a lot of image buttons, and you don't want to write xml-s for every button.
Kotlin Version:
fun buttonEffect(button: View) {
button.setOnTouchListener { v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
v.background.setColorFilter(-0x1f0b8adf, PorterDuff.Mode.SRC_ATOP)
v.invalidate()
}
MotionEvent.ACTION_UP -> {
v.background.clearColorFilter()
v.invalidate()
}
}
false
}
}
Java Version:
public static void buttonEffect(View button){
button.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
v.getBackground().setColorFilter(0xe0f47521,PorterDuff.Mode.SRC_ATOP);
v.invalidate();
break;
}
case MotionEvent.ACTION_UP: {
v.getBackground().clearColorFilter();
v.invalidate();
break;
}
}
return false;
}
});
}
Create bounce.xml file for animation
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration="100"
android:fromXScale="0.9"
android:fromYScale="0.9"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0" />
</set>
Add this line in onClick to initialize
final Animation myAnim = AnimationUtils.loadAnimation(this, R.anim.bounce); button.startAnimation(myAnim);
You get the shrink effect in a button click.
Making a minor addition to AndrĂ s answer:
You can use postDelayed
to make the color filter last for a small period of time to make it more noticeable:
@Override
public boolean onTouch(final View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
v.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
v.invalidate();
break;
}
case MotionEvent.ACTION_UP: {
v.postDelayed(new Runnable() {
@Override
public void run() {
v.getBackground().clearColorFilter();
v.invalidate();
}
}, 100L);
break;
}
}
return false;
}
You can change the value of the delay 100L to suit your needs.
If you're using xml background instead of IMG, just remove this :
<item>
<bitmap android:src="@drawable/YOURIMAGE"/>
</item>
from the 1st answer that @Ljdawson gave us.
Or using only one background image you can achive the click effect by using setOnTouchListener
Two ways
((Button)findViewById(R.id.testBth)).setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
Button view = (Button) v;
view.getBackground().setColorFilter(0x77000000, PorterDuff.Mode.SRC_ATOP);
v.invalidate();
break;
}
case MotionEvent.ACTION_UP:
// Your action here on button click
case MotionEvent.ACTION_CANCEL: {
Button view = (Button) v;
view.getBackground().clearColorFilter();
view.invalidate();
break;
}
}
return true;
}
});
And if you don't want to use setOnTouchLister
, the another way of achieving this is
myButton.getBackground().setColorFilter(.setColorFilter(0xF00, Mode.MULTIPLY);
StateListDrawable listDrawable = new StateListDrawable();
listDrawable.addState(new int[] {android.R.attr.state_pressed}, drawablePressed);
listDrawable.addState(new int[] {android.R.attr.defaultValue}, myButton);
myButton.setBackgroundDrawable(listDrawable);
Step: set a button in XML with onClick Action:
<Button
android:id="@+id/btnEditUserInfo"
style="?android:borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/txt_height"
android:layout_gravity="center"
android:background="@drawable/round_btn"
android:contentDescription="@string/image_view"
android:onClick="edit_user_info"
android:text="Edit"
android:textColor="#000"
android:textSize="@dimen/login_textSize" />
Step: on button clicked show animation point
//pgrm mark ---- ---- ----- ---- ---- ----- ---- ---- ----- ---- ---- -----
public void edit_user_info(View view) {
// show click effect on button pressed
final AlphaAnimation buttonClick = new AlphaAnimation(1F, 0.8F);
view.startAnimation(buttonClick);
Intent intent = new Intent(getApplicationContext(), EditUserInfo.class);
startActivity(intent);
}// end edit_user_info
You can simply use foreground for your View
to achieve clickable effect:
android:foreground="?android:attr/selectableItemBackground"
For use with dark theme add also theme to your layout
(to clickable effect be clear):
android:theme="@android:style/ThemeOverlay.Material.Dark"
This is the best solution I came up with taking hints from @Vinayak's answer. All the other solutions have different drawbacks.
First of all create a function like this.
void addClickEffect(View view)
{
Drawable drawableNormal = view.getBackground();
Drawable drawablePressed = view.getBackground().getConstantState().newDrawable();
drawablePressed.mutate();
drawablePressed.setColorFilter(Color.argb(50, 0, 0, 0), PorterDuff.Mode.SRC_ATOP);
StateListDrawable listDrawable = new StateListDrawable();
listDrawable.addState(new int[] {android.R.attr.state_pressed}, drawablePressed);
listDrawable.addState(new int[] {}, drawableNormal);
view.setBackground(listDrawable);
}
Explanation:
getConstantState().newDrawable() is used to clone the existing Drawable otherwise the same drawable will be used. Read more from here: Android: Cloning a drawable in order to make a StateListDrawable with filters
mutate() is used to make the Drawable clone not share its state with other instances of Drawable. Read more about it here: https://developer.android.com/reference/android/graphics/drawable/Drawable.html#mutate()
Usage:
You can pass any type of View (Button, ImageButton, View etc) as the parameter to the function and they will get the click effect applied to them.
addClickEffect(myButton);
addClickEffect(myImageButton);
For all the views
android:background="?android:attr/selectableItemBackground"
But for cardview which has elevation use
android:foreground="?android:attr/selectableItemBackground"
For Circular click effect as in toolbar
android:background="?android:attr/actionBarItemBackground"
Also you need to set
android:clickable="true"
android:focusable="true"
Source: Stackoverflow.com