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