How to set button click effect in Android?

后端 未结 14 2292
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-28 01:29

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.

相关标签:
14条回答
  • 2020-11-28 01:44

    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.

    0 讨论(0)
  • 2020-11-28 01:53

    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>

    0 讨论(0)
  • 2020-11-28 01:54

    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"
    
    0 讨论(0)
  • 2020-11-28 01:56

    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.

    0 讨论(0)
  • 2020-11-28 01:57

    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;
            }
        });
    }
    
    0 讨论(0)
  • 2020-11-28 01:58

    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.

    0 讨论(0)
提交回复
热议问题