Tôi có RecyclerView với 2 mục không lấp đầy toàn bộ màn hình. Làm cách nào để phát hiện người dùng đã nhấp vào phần trống của RecyclerView (có nghĩa là được nhấp trực tiếp trên RecyclerView chứ không phải một trong các mục của nó)?Phát hiện nhấp vào RecyclerView bên ngoài các mục
Trả lời
Bạn có thể phân lớp RecyclerView
và ghi đè phương thức dispatchTouchEvent()
để thực hiện việc này. Sử dụng phương pháp findChildViewUnder()
, chúng tôi có thể xác định xem sự kiện chạm có xảy ra bên ngoài Chế độ xem con không và sử dụng interface
để thông báo cho người nghe nếu có. Trong ví dụ sau, OnNoChildClickListener
interface
cung cấp chức năng đó.
public class TouchyRecyclerView extends RecyclerView
{
// Depending on how you're creating this View,
// you might need to specify additional constructors.
public TouchyRecyclerView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
private OnNoChildClickListener listener;
public interface OnNoChildClickListener
{
public void onNoChildClick();
}
public void setOnNoChildClickListener(OnNoChildClickListener listener)
{
this.listener = listener;
}
@Override
public boolean dispatchTouchEvent(MotionEvent event)
{
// The findChildViewUnder() method returns null if the touch event
// occurs outside of a child View.
// Change the MotionEvent action as needed. Here we use ACTION_DOWN
// as a simple, naive indication of a click.
if (event.getAction() == MotionEvent.ACTION_DOWN
&& findChildViewUnder(event.getX(), event.getY()) == null)
{
if (listener != null)
{
listener.onNoChildClick();
}
}
return super.dispatchTouchEvent(event);
}
}
NB: Đây là điều chỉnh cho RecyclerView
từ my answer here liên quan GridView
.
Như đã đề cập trong các bình luận
mRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
@Override
public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
if (motionEvent.getAction() != MotionEvent.ACTION_UP) {
return false;
}
View child = recyclerView.findChildViewUnder(motionEvent.getX(), motionEvent.getY());
if (child != null) {
// tapped on child
return false;
} else {
// Tap occured outside all child-views.
// do something
return true;
}
}
@Override
public void onTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
}
});
Cũng nên kiểm tra MotionEvent.getAction() == ACTION_UP, nếu không, bạn sẽ nhận được 2 sự kiện nhấp chuột. –
Cảm ơn @ greg-ennis. Tôi đã cập nhật mã. –
Đây phải là câu trả lời được chấp nhận. Nó cũng có thể là 'return false;' thay vì 'return;' bên dưới phần 'MotionEvent.ACTION_UP'. –
Bạn chỉ cần thiết lập một TouchListener
trên RecyclerView
như trình bày ở trên:
categoryTable.setAdapter(new CatgoriesAdapter(categories.getWrappedList()));
categoryTable.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN
&& categoryTable.findChildViewUnder(event.getX(), event.getY()) == null)
{
// Touch outside items here, you do whatever you want
HideCategoryMenu();
}
return false;
}
});
@ câu trả lời Driss-Bounouar được gần như ngay mặc dù điều này sẽ ngăn chặn sự người dùng di chuyển chế độ xem của người tái chế như bất kỳ sự kiện nào khác sẽ khiến hành động của bạn xảy ra. Với một sửa đổi nhỏ, nơi chúng tôi ghi lại sự kiện xuống và sau đó kiểm tra sự kiện lên nếu tọa độ không thay đổi nhiều, sau đó kích hoạt sự kiện.
private MotionEvent lastRecyclerViewDownTouchEvent;
myRecyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN && myRecyclerView.findChildViewUnder(event.getX(), event.getY()) == null) {
lastRecyclerViewDownTouchEvent = event;
} else if (event.getAction() == MotionEvent.ACTION_UP && myRecyclerView.findChildViewUnder(event.getX(), event.getY()) == null
&& lastRecyclerViewDownTouchEvent != null) {
// Check to see if it was a tap or a swipe
float xDelta = Math.abs(lastRecyclerViewDownTouchEvent.getX() - event.getX());
float yDelta = Math.abs(lastRecyclerViewDownTouchEvent.getY() - event.getY());
if (xDelta < 30 && yDelta < 30) {
// Do action
}
lastRecyclerViewDownTouchEvent = null;
}
return false;
}
});
- 1. Phát hiện nhấp vào phần tử bên ngoài?
- 2. Nhấp vào mục lập trình trong RecyclerView
- 3. Mục Recyclerview nhấp vào hiệu ứng gợn sóng
- 4. Kéo và thả xem bên ngoài Recyclerview
- 5. RecyclerView - các mục bên ngoài màn hình bỏ qua bố trí đầu tiên vượt qua
- 6. Cách phát hiện sự kiện chạm bên ngoài phần tử
- 7. Phát hiện nhấp chuột bên ngoài div bằng cách sử dụng javascript
- 8. toggle- ẩn mục khi nhấp bên ngoài div
- 9. Nhấp Floating ActionButton trên góc làm RecyclerView mục được nhấp
- 10. Xóa Phân đoạn bằng cách nhấp/chạm vào bên ngoài:
- 11. nhấp chuột bên ngoài DIV
- 12. Ẩn thành phần khi được nhấp vào bên ngoài
- 13. Ẩn thành phần khi nhấp vào bên ngoài
- 14. Phát hiện nhấp vào sự kiện nền
- 15. cách thay đổi bố cục của mục recyclerview từ bên ngoài?
- 16. jQuery ẩn nếu được nhấp vào bên ngoài nút
- 17. RecyclerView Vuốt bằng một cái nhìn dưới đây không phát hiện nhấp
- 18. phát hiện Nhấn vào yếu tố bên ngoài trong góc 4 sử dụng chỉ thị
- 19. Vô hiệu hóa nhấp chuột vào RecyclerView bên trong một SwipeRefreshLayout
- 20. Recyclerview addOnItemTouchListener nhận được xem ảnh nào được nhấp vào bên trong hàng
- 21. xóa các mục RecyclerView
- 22. PopupMenu nhấp vào gây ra RecyclerView để cuộn
- 23. Cách thêm thư mục tài nguyên bên ngoài vào JBoss7?
- 24. Phát hiện có nguồn gốc phản ứng nhấp vào WebView
- 25. Cách phát hiện sự kiện MouseUp bên ngoài cửa sổ?
- 26. Chọn các mục trong RecyclerView
- 27. Có thể nhấp vào hai mục cùng một lúc trong RecyclerView
- 28. ViewPager bên trong RecyclerView dưới dạng mục hàng
- 29. Phát hiện phần tử tôi nhấp vào trong UIWebView
- 30. Làm cách nào để phát hiện các nhấp chuột trên một phần tử bên trong một mục ion?
Cảm ơn bạn rất nhiều! Tôi đã kết thúc bằng cách sử dụng recyclerView.addOnItemTouchListener với findChildViewUnder (..). – Omar
@Omar Ah! Rất tốt! Tôi vẫn còn làm quen với RecyclerView, và tôi vẫn chưa biết về giao diện đó. Cảm ơn bạn về thông tin! Bạn nên tạo câu trả lời cho điều đó. Bạn sẽ nhận được một upvote từ tôi. –