Long press in specific duration

Trong nhiều trường hợp, chúng ta muốn tạo ra một listener để lắng nghe sự kiện long press vào một view trong một khoảng thời gian nào đó. Mặc định đến hiện giờ theo mình biết thì android chưa support sẵn hàm như vậy. Để làm được thì có thể đặt thời gian start ở onDown, sau đó khi chưa nhấc tay lên thì sẽ lấy thời gian hiện tại trừ đi startTime, khi nào lớn hơn giá trị duration thì coi như user vừa mới longpress. Tuy nhiên như vậy thì sẽ phải làm việc kiểm tra (currentTime - startTime) rất nhiều lần. Theo một hướng khác, ở đây mình sẽ sử dụng postDelayed để làm, cảm giác sẽ nhẹ nhàng hơn. Demo:

public static void setLongPress(final View view, final long duration){
		view.setOnTouchListener(new View.OnTouchListener() {
			private Handler handler = new Handler();
			private boolean isLongPress;
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()){
					case MotionEvent.ACTION_DOWN:
						isLongPress = true;
						handler.postDelayed(new Runnable() {
							@Override
							public void run() {
								if (isLongPress) {
									isLongPress = false;
									// Do something here
								}
							}
						}, duration);
						break;
					case MotionEvent.ACTION_CANCEL:
					case MotionEvent.ACTION_UP:
						if(isLongPress == false) {
							view.setPressed(false);
							return true;
						}
						isLongPress = false;
						handler.removeCallbacksAndMessages(null);
						break;
				}
				return false;
			}
		});
	}

Như vậy là ok rồi, tuy nhiên ở đây mình mới chỉ bắt ACTION_DOWN và ACTION_UP nên giả sử khi đang DOWN, mà move ra phía bên ngoài view, thì vẫn tính là đang long press, cho đến khi UP hoặc CANCEL. Để check thêm các trường hợp khác như MOVE, HOVER thì có thể kiểm tra thêm trong các trạng thái khác của event.getAction().

Goodbye 2017


All Rights Reserved