【问题标题】:How to set button click effect in Android?如何在Android中设置按钮点击效果?
【发布时间】:2011-11-02 19:16:00
【问题描述】:

在 Android 中,当我为按钮设置背景图像时,单击它时看不到任何效果。

我需要在按钮上设置一些效果,这样用户才能识别出按钮被点击了。

单击按钮后,该按钮应该会变暗几秒钟。如何做到这一点?

【问题讨论】:

标签: android


【解决方案1】:

这可以通过创建一个包含按钮状态列表的可绘制 xml 文件来实现。例如,如果您使用以下代码创建一个名为“button.xml”的新 xml 文件:

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

要使背景图像在印刷时保持较暗的外观,请创建第二个 xml 文件并使用以下代码将其命名为 gradient.xml:

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

在按钮的 xml 中,将背景设置为按钮 xml,例如

android:background="@drawable/button"

希望这会有所帮助!

编辑:将上面的代码更改为在按钮中显示图像(YOURIMAGE)而不是块颜色。

【讨论】:

  • 那么我在哪里可以设置按钮背景的图像,设置图像是必须的
  • 已编辑以显示如何使用带有状态 XML 的背景图像。将 YOURIMAGE 替换为可绘制目录中的图像资源。
  • 这仅适用于按钮的 src 是矩形的。如果 src drawable 有任何不同的形状,渐变也会应用到背景上,这很可悲。
  • 不是真的,总是可以在图层列表中使用不同的形状
  • 当我使用图像时,它对我有用.. 但是当我使用 Xml 背景时。它不工作......
【解决方案2】:

当你有很多图片按钮时会更简单,而且你不想为每个按钮都写xml-s。

Kotlin 版本:

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 版本:

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

【讨论】:

  • 我在我的代码中使用了它,到目前为止我注意到的唯一问题是按钮在放置在 ScrollView 时的行为很奇怪。
  • 这真的是极好的解决方案,这应该是正确的答案
  • 这样更好吗?设计应该远离代码,不是吗?
  • 这只是解决这个问题的简单方法。当您有很多按钮并且不想为每个按钮都创建 xml 时,这可能会有所帮助。
  • 天哪!想象一下在一个片段中有 5 个按钮......你将拥有一大堆样板代码......那么如何重构它?更改所有活动中所有按钮的颜色过滤器?恕我直言,你的下一个开发者不会这么高兴..
【解决方案3】:

创建您的AlphaAnimation 对象,该对象决定按钮的淡入淡出效果,然后让它从您的按钮的onClickListener 开始

例如:

private AlphaAnimation buttonClick = new AlphaAnimation(1F, 0.8F);

// some code

public void onClick(View v) {
    v.startAnimation(buttonClick);
}

当然这只是一种方式,不是最喜欢的方式,只是更简单

【讨论】:

  • 我喜欢这个解决方案的一点是,它不需要创建很多选择器,因为您有很多按钮,每个按钮都有自己的自定义图像。
  • 这不会在按下时淡出按钮,它只会在检测到点击并且用户的手指已经抬起后才淡出一秒钟。
  • 又好又简单
  • @Doug Voss,你可以设置动画的时长让它变长
  • onLongClick 和 'circularReveal' 怎么样?
【解决方案4】:

您可以为您的View简单地使用前景来实现可点击效果:

android:foreground="?android:attr/selectableItemBackground"


要与深色主题一起使用,请将 theme 添加到您的 layout (以使可点击效果清晰):

android:theme="@android:style/ThemeOverlay.Material.Dark"

【讨论】:

  • 最简单的实现方式。仅供参考,属性 android:foreground 对低于 23 的 API 级别没有影响。
  • 最简单的解决方案。
  • 这应该是公认的答案,更简单,并且增加了漂亮的波纹动画效果。
  • @dolgom 对于 API 级别
  • @Z3R0 android:background="@drawable/bluebutton" 已用于设置按钮的图像。不能用两次。因此,较旧的 Android 版本不走运。如果按钮没有透明度,则只有接受的解决方案有效。
【解决方案5】:

要使您的项目与系统外观和感觉保持一致,请尝试在所需视图的背景或前景标记中引用系统属性android:attr/selectableItemBackground:

<ImageView
    ...
    android:background="?android:attr/selectableItemBackground"      
    android:foreground="?android:attr/selectableItemBackground"
    ...
/>

在 API 级别 23 之前/之后分别使用这两个属性来获得所需的效果。

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

【讨论】:

  • 迄今为止最简单的解决方案。谢谢!
  • 但是您使用的是 ImageView,而不是背景设置为图像的 Button。
  • @Houman 它适用于 ImageButton 甚至 LinearLayout 等
【解决方案6】:

或者只使用一张背景图片可以通过setOnTouchListener实现点击效果

两种方式

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

如果你不想使用setOnTouchLister,另一种实现方式是

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

【讨论】:

  • 第二种方式的代码有错误。什么是 getCurrent() 函数? myButton 也不是 Drawable,因此不能作为状态添加。
  • 感谢您指出错误。我已经更正了它,myButton 是 Button 类的一个实例,它提供方法 setBackgroundDrawable 并且它采用 Drawable 实例,因此这将起作用。
  • 查看我基于您的第二种方法的答案。 stackoverflow.com/a/39430738/5229515
  • 这应该在最后有“return false”这样它不会消耗事件并且可以调用任何额外的onClickListeners。
【解决方案7】:

所有视图

android:background="?android:attr/selectableItemBackground"

但是对于有海拔使用的cardview

android:foreground="?android:attr/selectableItemBackground"

工具栏中的圆形点击效果

android:background="?android:attr/actionBarItemBackground"

还需要设置

 android:clickable="true"
 android:focusable="true"

【讨论】:

  • 我不明白你的意思。 android:background="@drawable/bluebutton" 用于将 Button 的背景设置为图像。它已经被占用了。这行不通。
  • @Houman 你可以使用波纹stackoverflow.com/a/40008782/8663316
【解决方案8】:

这是我从@Vinayak 的回答中得出的最佳解决方案。所有其他解决方案都有不同的缺点。

首先创建一个这样的函数。

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

说明:

getConstantState().newDrawable() 用于克隆现有的Drawable,否则将使用相同的drawable。从这里阅读更多信息: Android: Cloning a drawable in order to make a StateListDrawable with filters

mutate() 用于使 Drawable 克隆不与其他 Drawable 实例共享其状态。在此处阅读更多信息: https://developer.android.com/reference/android/graphics/drawable/Drawable.html#mutate()

用法:

您可以将任何类型的视图(按钮、图像按钮、视图等)作为参数传递给函数,它们将获得应用到它们的点击效果。

addClickEffect(myButton);
addClickEffect(myImageButton);

【讨论】:

    【解决方案9】:

    只是想添加另一种简单的方法来做到这一点:如果您的 ImageButton 保持其背景并且您没有将其设置为 null,它将像普通按钮一样工作,并且会在单击时显示单击动画,与其他按钮完全一样。隐藏仍然存在的背景的方法:

    <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" />
    

    填充不会让背景可见并使按钮的行为与其他按钮一样。

    【讨论】:

    • 如果它是圆形的,这将在图像周围保留方形按钮边框
    【解决方案10】:
    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
    

    【讨论】:

      【解决方案11】:

      将 RippleDrawable 用于 Material Design 状态按下/点击效果。

      为了实现这一点,在 /drawable 文件夹下创建一个 .xml 的涟漪项目,并将其用于任何视图的 android:background 中。

      • 图标按下/点击的效果,使用圆形波纹效果,例如:

        <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@android:color/darker_gray" />

      • 对于点击矩形边界的视图的效果,我们可以在现有的可绘制对象上添加波纹,如下所示:

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

      【讨论】:

        【解决方案12】:

        为动画创建bounce.xml文件

        位置:

        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>
        

        在onClick中加入这一行进行初始化

          final Animation myAnim = AnimationUtils.loadAnimation(this,R.anim.bounce);
                 button.startAnimation(myAnim);
        

        单击按钮即可获得缩小效果。

        【讨论】:

          【解决方案13】:

          我遇到了同样的问题,我需要一个透明的背景,但仍然可以获得动画。设置它为我解决了它:

          android:background="?android:selectableItemBackground"
          

          如果你想有循环效果,也可以这样:

          android:background="?android:selectableItemBackgroundBorderless"
          

          【讨论】:

            【解决方案14】:

            对 Andràs 的回答稍作补充:

            您可以使用postDelayed 使滤色器持续一小段时间以使其更明显:

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

            您可以根据需要更改延迟 100L 的值。

            【讨论】:

              【解决方案15】:

              如果您使用的是 xml 背景而不是 IMG,只需将其删除:

              <item>
                  <bitmap android:src="@drawable/YOURIMAGE"/>
              </item>
              

              @Ljdawson 给我们的第一个答案。

              【讨论】:

                【解决方案16】:

                设置查看点击效果的简单方法。

                方法

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

                在视图中设置

                yourView.startAnimation(clickAnimation());
                

                【讨论】:

                  猜你喜欢
                  • 2016-05-25
                  • 1970-01-01
                  • 2014-09-02
                  • 1970-01-01
                  • 2020-01-17
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-03-26
                  • 1970-01-01
                  相关资源
                  最近更新 更多