How to set button click effect in Android?

Android

Android Problem Overview


In Android, when I set a background image to a button, I can not see any effect on it when it's clicked.

I need to set some effect on the button, so the user can recognise that the button is clicked.

The button should be dark for a few seconds when it is clicked. How to do this?

Android Solutions


Solution 1 - Android

This can be achieved by creating a drawable xml file containing a list of states for the button. So for example if you create a new xml file called "button.xml" with the following code:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
	<item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/YOURIMAGE" />
	<item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/gradient" />
	<item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/gradient" />
	<item android:drawable="@drawable/YOURIMAGE" />
</selector>

To keep the background image with a darkened appearance on press, create a second xml file and call it gradient.xml with the following code:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
	<item>
		<bitmap android:src="@drawable/YOURIMAGE"/>
	</item>
	<item>
		<shape xmlns:android="http://schemas.android.com/apk/res/android">
			<gradient android:angle="90" android:startColor="#880f0f10" android:centerColor="#880d0d0f" android:endColor="#885d5d5e"/>
		</shape>
	</item>
</layer-list>

In the xml of your button set the background to be the button xml e.g.

android:background="@drawable/button"

Hope this helps!

Edit: Changed the above code to show an image (YOURIMAGE) in the button as opposed to a block colour.

Solution 2 - Android

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;
        }
    });
}

Solution 3 - 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

Solution 4 - Android

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"

Solution 5 - Android

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.

https://stackoverflow.com/a/11513474/4683601

Solution 6 - Android

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;
        }
});

enter image description here

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);

Solution 7 - Android

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"

Solution 8 - Android

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: https://stackoverflow.com/questions/7979440/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);

Solution 9 - Android

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.

Solution 10 - Android

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

Solution 11 - Android

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>

Solution 12 - Android

Create bounce.xml file fo animation

LOCATION:

> res->anim->bounce.xml

<?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.

Solution 13 - Android

I had the same issue, where I needed to have a transparent background but still get animation. Setting this solved it for me:

android:background="?android:selectableItemBackground"

Also this if you want to have circular effect:

android:background="?android:selectableItemBackgroundBorderless"

Solution 14 - Android

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.

Solution 15 - Android

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.

Solution 16 - Android

Simple and easy way to set View click effect.

> Method

public AlphaAnimation clickAnimation() {
    return new AlphaAnimation(1F, 0.4F); // Change "0.4F" as per your recruitment.
}

> Set in View

yourView.startAnimation(clickAnimation());

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJignesh AnsodariyaView Question on Stackoverflow
Solution 1 - AndroidLjdawsonView Answer on Stackoverflow
Solution 2 - AndroidAndrásView Answer on Stackoverflow
Solution 3 - AndroidAhmed Adel IsmailView Answer on Stackoverflow
Solution 4 - AndroidFrancisView Answer on Stackoverflow
Solution 5 - AndroidEly DantasView Answer on Stackoverflow
Solution 6 - AndroidVinayak BevinakattiView Answer on Stackoverflow
Solution 7 - AndroidFaizan Haidar KhanView Answer on Stackoverflow
Solution 8 - AndroidEhtesham HasanView Answer on Stackoverflow
Solution 9 - AndroidarianooView Answer on Stackoverflow
Solution 10 - AndroidVinod JoshiView Answer on Stackoverflow
Solution 11 - Androidgiang nguyenView Answer on Stackoverflow
Solution 12 - AndroidArpit PatelView Answer on Stackoverflow
Solution 13 - AndroidMandelMechView Answer on Stackoverflow
Solution 14 - Androidhiddeneyes02View Answer on Stackoverflow
Solution 15 - AndroidRastaPopuloSView Answer on Stackoverflow
Solution 16 - AndroidKumar SantanuView Answer on Stackoverflow