Button整理

本文详细介绍了Button与TextView的区别,以及如何设置Button的点击事件,包括使用`android:onClick`属性和设置`OnClickListener`。此外,还讲解了改变Button样式的多种方法,如使用系统样式、自定义背景和整体样式,并提供了防止过快点击Button导致多次请求的解决方案。

Button整理

Button与TextView的区别

Button继承自TextView,它与TextView的区别只是多了一个样式,该样式会根据app的Theme不同而不同,找到这个样式来看看定义了什么内容。

  1. Button其中一个构造方法,设置了buttonStyle 样式

    public Button(Context context, AttributeSet attrs) {
            this(context, attrs, com.android.internal.R.attr.buttonStyle);
        }
  2. 由此我们知道Button的样式名为buttonStyle
  3. 我们到app当前所使用的Theme下查找该样式,我当前使用的Theme是Theme.AppCompat.Light.DarkActionBar ,直接点击进入Theme查找buttonStyle

    <!-- Button styles -->
    <item name="buttonStyle">@style/Widget.AppCompat.Button</item>      
  4. 最终找到该样式
<style name="Base.Widget.AppCompat.Button" parent="android:Widget">
        <item name="android:background">@drawable/abc_btn_default_mtrl_shape</item>
        <item name="android:textAppearance">?android:attr/textAppearanceButton</item>
        <item name="android:minHeight">48dip</item>
        <item name="android:minWidth">88dip</item>
        <item name="android:focusable">true</item>
        <item name="android:clickable">true</item>
        <item name="android:gravity">center_vertical|center_horizontal</item>
    </style>

在这里我们可以看到系统Button的默认背景,字体样式,最小宽高的值,具备焦点,可点击,内部内容时居中对齐的设置.TextView与Button的区别就是这些设置,其中的android:clickable 是核心,TextView设置该属性后,也可以实现点击的功能.我们有时因Button限定了宽高,而不得不自己定义Button,我们完全可以使用TextView实现Button的功能

设置Button的点击事件

方式一: 使用android:onClick=”methodName”属性
  • xml设置android:onClick=”methodName”
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/button_send"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/button_send"
    android:onClick="sendMessage" />
  • Activity中编写相同名称的方法,即sendMessage方法
  • 该方法必须具备官方要求的编写规范才能生效
    • 方法权限为public
    • 返回值为void
    • 方法参数为View
/** Called when the user touches the button */
public void sendMessage(View view) {
    // Do something in response to button click
}
方式二: 使用 OnClickListener设置事件监听
Button button = (Button) findViewById(R.id.button_send);
button.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        // Do something in response to button click
    }
});

改变Button样式

使用系统自带Button样式,style=”?android:attr/selectButtonStytle”
<Button
    android:id="@+id/button_send"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/button_send"
    android:onClick="sendMessage"
    style="?android:attr/borderlessButtonStyle" />
自定义Button背景
  1. 为Button的三个状态分别创建对应的图片或者shape,这三个状态分别为android:state_pressedandroid:state_focused,默认状态;
  2. 将背景资源放在res/drawable/ 中,如果背景资源是图片,建议使用.9图片,因为普通图片做为背景会出现图片拉伸的情况;如果使用的是shape则没有这方面顾虑;
  3. res/drawable/ 中创建selector文件

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/button_pressed"
              android:state_pressed="true" />
        <item android:drawable="@drawable/button_focused"
              android:state_focused="true" />
        <item android:drawable="@drawable/button_default" />
    </selector>

    注意:Button根据状态不同从上到下的查找对应的drawable,当没有对应的状态表示时,会使用最后的默认状态,所以默认状态是必须的,不能省略。否则有可能出现错误

  4. 使用自定义背景

    <Button
        android:id="@+id/button_send"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button_send"
        android:onClick="sendMessage"
        android:background="@drawable/button_custom"  />
自定义Button样式

自定义Button背景与自定义Button样式是两个不同的概念,自定义Button背景仅仅是对buttonStyle 中的android:background 属性的值进行修改,而自定义Button样式,则是修改Button的所有样式属性

  • 自定义Button背景很容易,但是如果我们想重新定义一个全新的Button,包括Button的背景,大小,字体等等,这时候就需要重新Button的样式了
  • 重新定义Button的样式,其实就是针对当前Button的样式进行覆盖
  • 我们可以直接使用style="?android:attr/buttonBarButtonStyle" 修改Button的样式,但是这样修改,只是修改某个Button的样式,如果我们的app需要更换所有的Button样式,显然这种方式非常的麻烦
  • 修改全局Button样式(我们只需在Theme中重新定义buttonStyle)
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:buttonStyle">@style/ButtonStyle</item>
    </style>

    <style name="ButtonStyle" parent="@android:style/Widget.Button">
        <item name="android:background">@drawable/selector_button_custom</item>
        <item name="android:minHeight">100dp</item>
        <item name="android:minWidth">100dp</item>
    </style>

</resources>

注意:修改buttonStyle时必须继承@android:style/Widget.Button

防止过快点击Button导致多次请求的问题

开发中,我们会经常遇到点击按钮请求数据时,请求的结果还没接收到,再次点击按钮时,会出现二次请求的情况发生。
查找资料后发现,有两种方式可以解决该问题
1. mButton.setEnable(true);或者mButton.setClickable(true);禁用和开启Button

开启请求后,通过以上两种方式禁用Button的点击事件,在请求成功后,再启用Button的点击事件,注意:在请求失败时,也需要启用Button,否则会出现请求数据失败,Button也无法点击的尴尬局面
缺点:当项目中有许多类似的Button时,这样的处理方式过于繁琐,需要在多处开启和禁用Button。
2. 控制Button的点击间隔时间,来响应点击事件

  • 实现View.OnClickListener重写onClick方法,控制点击的时间间隔

    public abstract class OnNoMultiClickListener implements View.OnClickListener {
    
        private static final String TAG = "OnNoMultiClickListener";
    
        private final static long MINI_INTERVAL_TIME = 500;
        private long lastClickTime;
    
        @Override
        public void onClick(View v) {
            long time = System.currentTimeMillis();
            if (time - lastClickTime > MINI_INTERVAL_TIME) {
                onNoMultiClick(v);
            } else {
                Log.i(TAG, "Too fast click");
            }
            lastClickTime = time;
        }
    
        public abstract void onNoMultiClick(View v);
    }
  • 使用

    ```
    Button buttonClick = (Button) findViewById(R.id.btn_click);
            if (buttonClick != null) {
                buttonClick.setOnClickListener(new OnNoMultiClickListener() {
                    @Override
                    public void onNoMultiClick(View v) {
                        Toast.makeText(MainActivity.this, R.string.Button_click, Toast.LENGTH_SHORT).show();
                    }
                });
            }
    ```
    

    用工具类的方式进行点击事件间隔判断,也可以达到同样的效果,但是这里不建议使用。因为这种方式使用起来,没有上述方式优雅。它需要在每个禁止多次点击的Button处,进行判断。

参考资料:Android:防止过快点击造成多次事件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值