LoginSignup
16
16

More than 5 years have passed since last update.

お手軽にAndroidのButtonの連打を防止してみた

Last updated at Posted at 2017-07-20

目的

  • Androidアプリにおいて、ボタンを連打されると困るので、連打できないようにしたい。

実装!

Button(AppCompatButton)を継承したButtonクラスを追加

app/src/main/java/com/example/barrageguardbuttondemo/utils/BarrageGuardButton.java
package com.example.barrageguardbuttondemo.utils; // Replace with your package

import android.content.Context;
import android.os.Handler;
import android.support.v7.widget.AppCompatButton;
import android.util.AttributeSet;
import android.view.View;

/**
 * 連打防止Buttonクラス
 */
public class BarrageGuardButton extends AppCompatButton {
    public BarrageGuardButton(Context context) {
        super(context);
    }

    public BarrageGuardButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public BarrageGuardButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setOnClickListener(final View.OnClickListener listener) {
        super.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(final View view) {

                view.setEnabled(false);
                new Handler().postDelayed(new Runnable() {
                    public void run() {
                        view.setEnabled(true);
                    }
                }, 3000L);

                listener.onClick(view);
            }
        });
    }
}

Layout xml にButtonを追加 or 既存のボタンのタグを置換

app/src/main/res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:gravity="center"
  tools:context="com.example.barrageguardbuttondemo.MainActivity">

  <com.example.barrageguardbuttondemo.utils.BarrageGuardButton
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click here"/>
</LinearLayout>

ClickListenerをセット

app/src/main/java/com/example/barrageguardbuttondemo/MainActivity.java
package com.example.barrageguardbuttondemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import com.example.barrageguardbuttondemo.utils.BarrageGuardButton;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ((BarrageGuardButton) findViewById(R.id.button1)).setOnClickListener(
            new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(MainActivity.this, "It works!!!", Toast.LENGTH_SHORT).show();
                }
            });
    }
}

以上で完了です!これでボタンをタップすると一定時間enabled:falseになり、連打ができなくなります。
既存コードで実装する場合は、xmlのButtonタグを置換するだけで振る舞いを変えることができます。

おまけ

BarrageGuardButton は Buttonクラス(今回は android.support.v7.widget.AppCompatButton ) を継承しているので、そのままDataBindingの表記にも対応できます。

app/build.gradle
apply plugin: 'com.android.application'

android {

    ...

    dataBinding {
      enabled = true
    }
}
app/src/main/res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools">

  <data>
    <variable
      name="activity"
      type="com.example.barrageguardbuttondemo.MainActivity"/>
  </data>

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    tools:context="com.example.barrageguardbuttondemo.MainActivity">

    <com.example.barrageguardbuttondemo.utils.BarrageGuardButton
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:onClick="@{activity::onClickDemoButton}"
      android:text="Click here"/>
  </LinearLayout>
</layout>
app/src/main/java/com/example/barrageguardbuttondemo/MainActivity.java
package com.example.barrageguardbuttondemo;

import android.databinding.DataBindingUtil;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import com.example.barrageguardbuttondemo.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        binding.setActivity(this);
    }

    public void onClickDemoButton(View view) {
        Toast.makeText(MainActivity.this, "It works!!!", Toast.LENGTH_SHORT).show();
    }
}

こんな感じに書いてもバッチリ動作します!

DataBindingについてはこちら : https://developer.android.com
(日本語の方もだいぶ整ってきましたね)

一応サンプルプロジェクトをGitHubで公開しています : https://github.com/sasakii/BarrageGuardButtonDemo

動作確認

demo
※ GIFにしたせいで若干汚いですがご了承を

16
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
16