Один метод для реализации onTouchListener() для нескольких кнопок
Я пытаюсь понять, есть ли способ создать один метод для реализации сенсорного прослушивателя для нескольких кнопок, поскольку у меня есть довольно много кнопок, которые делают почти то же самое. Единственная разница в том, что они делают, - это сообщение, которое они отправят через мой метод sendMessage (), и как долго нужно удерживать кнопку, чтобы сообщение было отправлено. Если есть способ сделать это, что это может быть? И кроме того, почему бы не сделать что-то подобное работа?
//Within onCreate Method...
Button mButton = (Button) findViewbyId(R.id.three_sec_button);
mButton = addTouchTimer(mButton, 3, 3);
Вызовы -
private Button addTouchTimer(Button button, final int sec, final int messageNum){
button.setOnTouchListener(new View.OnTouchListener() {
boolean longEnough = false;
long realTimeLeft = sec * 1000;
@Override
// This will make it so that a message is only sent if the button is held down for 3 seconds
// Otherwise it won't send. It is sent during the hold down process, releasing it returns a false
// value and no message is sent.
public boolean onTouch(View arg0, MotionEvent arg1) {
Log.d("Button", "Touchy Touchy!");
if(arg1.getAction() == MotionEvent.ACTION_DOWN){
buttonPressTime = new CountDownTimer(realTimeLeft, 1000){
@Override
public void onTick(long millisUntilDone){
realTimeLeft = millisUntilDone;
}
@Override
public void onFinish() {
long timeLeft = realTimeLeft;
long currTime = System.currentTimeMillis();
long realFinishTime = currTime + timeLeft;
while(currTime < realFinishTime){
currTime = System.currentTimeMillis();
}
longEnough = true;
sendEmergencyMessage(longEnough, messageNum);
}
}.start();
}
else if(arg1.getAction() == MotionEvent.ACTION_UP){
buttonPressTime.cancel();
sendMessage(longEnough, messageNum);
}
return longEnough;
}
});
return button;
}
Просто кажется, что ради эффективности должен быть лучший способ сделать это, чем реализация отдельных слушателей для каждой кнопки. В качестве примечания, sendMessage () имеет вызов журнала в нем, который использует логическое значение, я хочу видеть, как оно устанавливается, когда оно передается. Это единственная причина, по которой он вызывается при отпускании кнопки.
7 ответов:
Да, вы правы, есть лучший способ. Один TouchListener, который обрабатывает все, определяя, какая кнопка это через идентификатор.
void intialization(){ Button m1, m2, m3, m4; ... //do initialization stuff m1.setId(1); m2.setId(2); m3.setId(3); m4.setId(4); MyTouchListener touchListener = new MyTouchListener(); m1.setOnTouchListener(touchListener); m2.setOnTouchListener(touchListener); m3.setOnTouchListener(touchListener); m4.setOnTouchListener(touchListener); } public class MyTouchListener implements OnTouchListener { @Override public boolean onTouch(View v, MotionEvent event) { switch(v.getId()){ case 1: //do stuff for button 1 break; case 2: //do stuff for button 2 break; case 3: //do stuff for button 3 break; case 4: //do stuff for button 4 break; } return true; } }
И вот как ты это сделаешь! Численный подход для идентификаторов очень полезен в этом случае. Другой подход заключается в том, чтобы ваша активность реализовала OnTouchListener в вашей активности, и тогда ваш код был бы еще проще.
public class MyActivity extends Activity implements OnTouchListener { void initialization(){ Button m1, m2, m3, m4; ... //do initialization stuff m1.setId(1); m2.setId(2); m3.setId(3); m4.setId(4); m1.setOnTouchListener(this); m2.setOnTouchListener(this); m3.setOnTouchListener(this); m4.setOnTouchListener(this); } @Override public boolean onTouch(View v, MotionEvent event) { switch(v.getId()){ case 1: //do stuff for button 1 break; case 2: //do stuff for button 2 break; case 3: //do stuff for button 3 break; case 4: //do stuff for button 4 break; } return true; } }
Примечание: этот подход также будет работать для OnClickListener, OnCheckedChangeListener или любого другого слушатель, который вы хотели установить на Андроид.
С ButterKnife это было бы так. (в моем случае ImageView как кнопки)
@OnTouch({R.id.Button1, R.id.Button2, R.id.Button3}) public boolean buttonsTouched(ImageView button, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: --(Your ACTION on Pressed)-- return true; case MotionEvent.ACTION_UP: --(Your ACTION on Release)-- return true; } return true; }
Да, есть лучший способ сделать то же самое.
1) Сделайте так, чтобы ваш класс реализовалOnTouchListener
.
2) Добавьте этот прослушиватель к каждой кнопке, которая должна обрабатывать событие касания. Вот так:button1.setOnTouchListener(this);
3) и в этом
public boolean onTouch(View arg0, MotionEvent arg1) {});
Метод вы можете использовать переключатель case на вид, который был затронут . Первый аргумент, т. е.
arg0
- это представление, в которое было отправлено событие касания. В вашем случае это будут разные кнопки. Что-то вроде этого:public boolean onTouch(View arg0, MotionEvent arg1) { if (arg1.getAction() == MotionEvent.ACTION_DOWN) { switch (arg0.getId()) { case R.id.button1: // Id of the button // Your code goes here break; case R.id.button2: // Id of the button // Your code goes here break; default: break; } } return true; }
OnTouchListener mOnTouchListener = new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // Code goes here return true; } }; button1.setOnTouchListener(mOnTouchListener); button2.setOnTouchListener(mOnTouchListener);
Я сливаю два ответа, это мой код
public class MyActivity extends Activity implements OnTouchListener { Button mGreen, mRed; void initialization() { ... //do initialization stuff mGreen.setOnTouchListener(this); mRed.setOnTouchListener(this); } @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: actionDown(); break; case MotionEvent.ACTION_UP: actionUp(); break; case MotionEvent.ACTION_POINTER_DOWN: break; case MotionEvent.ACTION_POINTER_UP: break; case MotionEvent.ACTION_MOVE: actionMove(); break; } return true; } public void actionDown() { switch (view.getId()) { case R.id.button_green: //todo break; case R.id.button_red: //todo break; } } public void actionUp() { switch (view.getId()) { case R.id.button_green: //todo break; case R.id.button_red: //todo break; } } public void actionMove() { switch (view.getId()) { case R.id.button_green: // todo break; case R.id.button_red: // todo break; } }}
Я надеюсь, что этот код кому-то поможет
Почему бы тебе не воспользоваться ножом для масла?
@Nullable @OnClick({R.id.btn1, R.id.btn2,R.id.btn3, R.id.btn4}) public void doStuff(Button button) {}
@Override public boolean onTouch(View view, MotionEvent motionEvent) { switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: shouldClick = true; . . break; case MotionEvent.ACTION_UP: if (shouldClick) view.performClick(); break; case MotionEvent.ACTION_POINTER_DOWN: break; case MotionEvent.ACTION_POINTER_UP: break; case MotionEvent.ACTION_MOVE: //Do your stuff shouldClick = false; break; } rootLayout.invalidate(); return true; }