キーリピートを実装する
Buttonクラスを拡張して、長押しされている場合クリック動作を呼び出すようにします。
RepeatButton.java
import android.content.Context; import android.os.Handler; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.View.OnLongClickListener; import android.widget.Button; public class RepeatButton extends Button implements OnLongClickListener { /** * 連続してボタンを押す間隔(ms) */ private static final int REPEAT_INTERVAL = 100; /** * 連打フラグ */ private boolean isContinue = true; /** * ハンドラ */ private Handler handler; public RepeatButton(Context context, AttributeSet attrs) { super(context, attrs); setOnLongClickListener(this); handler = new Handler(); } @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); // キーから指が離されたら連打をオフにする if (event.getAction() == MotionEvent.ACTION_UP) { isContinue = false; } return true; } @Override public boolean onLongClick(View v) { isContinue = true; // 長押しをきっかけに連打を開始する handler.post(repeatRunnable); return true; } Runnable repeatRunnable = new Runnable() { @Override public void run() { // 連打フラグをみて処理を続けるか判断する if (!isContinue) { return; } // クリック処理を実行する performClick(); // 連打間隔を過ぎた後に、再び自分を呼び出す handler.postDelayed(this, REPEAT_INTERVAL); } }; }
使用例
こんな感じで使えばNumberPicker的に使えます
MainActivity.java
import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener { private TextView txtNumber; private RepeatButton btnIncrement; private RepeatButton btnDecrement; private int number = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); txtNumber = (TextView)findViewById(R.id.txtNumber); txtNumber.setText(String.valueOf(number)); btnIncrement = (RepeatButton)findViewById(R.id.btnIncrement); btnIncrement.setOnClickListener(this); btnDecrement = (RepeatButton)findViewById(R.id.btnDecrement); btnDecrement.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btnIncrement: { increment(); break; } case R.id.btnDecrement: { decrement(); break; } } } private void increment() { number++; txtNumber.setText(String.valueOf(number)); } private void decrement() { number--; txtNumber.setText(String.valueOf(number)); } }
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:gravity="center_vertical|center_horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent"> <view class="jp.tomorrowkey.android.repeatpushbutton.RepeatButton" android:id="@+id/btnIncrement" android:text="Increment" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/txtNumber" android:text="0" android:textSize="32sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <view class="jp.tomorrowkey.android.repeatpushbutton.RepeatButton" android:id="@+id/btnDecrement" android:text="Decrement" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
独自Viewの定義の仕方
独自ViewのXMLの定義の仕方は2つあります
viewタグを使う場合
<view class="jp.tomorrowkey.android.repeatpushbutton.RepeatButton" android:layout_width="wrap_content" android:layout_height="wrap_content" />