2011-11-10 22 views
9

Tôi đang cố gắng để có được nhiều sự kiện cảm ứng trên chế độ xem lớp phủ hệ thống, nhưng tôi chỉ nhận được sự kiện MotionEvent.ACTION_OUTSIDE.Android: Multi touch và TYPE_SYSTEM_OVERLAY

Có cách nào có thể nhận được nhiều sự kiện chạm trên lớp phủ hệ thống không?

Bất kỳ ví dụ hoặc liên kết nào sẽ rất hữu ích.

Trả lời

24

Để tạo chế độ xem lớp phủ, khi thiết lập LayoutParams, bạn cần đặt loại thành TYPE_SYSTEM_OVERLAY và sử dụng cờ FLAG_WATCH_OUTSIDE_TOUCH. Điều này thể hiện sự cố vì tài liệu Android nêu rõ:

bạn sẽ không nhận được cử chỉ đầy đủ/di chuyển/lên, chỉ vị trí đầu tiên dưới dạng ACTION_OUTSIDE.

Để nhận được đầy đủ các sự kiện chạm bạn cần sử dụng loại TYPE_SYSTEM_ALERT, nhưng điều này khiến lớp phủ chiếm màn hình và ngừng tương tác với các yếu tố khác. Giải pháp là sử dụng cả hai TYPE_SYSTEM_OVERLAYTYPE_SYSTEM_ALERT và chuyển đổi giữa chúng bằng cách thay đổi loại LayoutParams nếu cần.

này được thực hiện bằng cách:

  1. Coi chừng các sự kiện ACTION_OUTSIDE chuyển động.
  2. Khi nó xảy ra, hãy kiểm tra xem nó có xảy ra trong lớp phủ hay không.
  3. Nếu nó đã làm, chuyển đổi các loại LayoutParams-TYPE_SYSTEM_ALERT
  4. Khi sự tương tác với lớp phủ hoàn tất, chuyển về TYPE_SYSTEM_OVERLAY
  5. Lặp lại

Một điều cần lưu ý là các ACTION_OUTSIDE sự kiện chuyển động luôn được truyền cho các phần tử còn lại trên màn hình. Vì vậy, ví dụ, nếu lớp phủ nằm trên đầu một nút, nút đó cũng sẽ nhận được sự kiện chuyển động và không có cách nào để ngăn chặn nó.

Cũng đảm bảo rằng bạn thêm quyền đối với tệp chính vào số SYSTEM_ALERT_WINDOW.

tôi đã đăng các giải pháp hoàn chỉnh ở đây:
http://www.jawsware.mobi/code_OverlayView/(UPDATED)

Nó bao gồm tất cả các mã nguồn và một liên kết để tải toàn bộ dự án ví dụ.


Cập nhật dành cho Android 4.0 - 1/3/2013


Để tạo một cái nhìn overlay, khi thiết lập LayoutParams KHÔNG đặt kiểu để TYPE_SYSTEM_OVERLAY.

Thay vì đặt thành TYPE_PHONE.

Sử dụng các cờ sau:

FLAG_NOT_TOUCH_MODAL

FLAG_WATCH_OUTSIDE_TOUCH

FLAG_NOT_TOUCH_MODAL < < tôi tìm thấy này là khá quan trọng. Nếu không có nó, tiêu điểm được đưa ra cho lớp phủ và các phím mềm (nhà, menu, vv) không được chuyển đến hoạt động bên dưới.

Ngoài ra, liên kết trước (ở trên) đã được cập nhật để phản ánh bản cập nhật này.

+1

Cảm ơn bạn đã cập nhật Jawsware. Nhưng với logic của bạn, tôi cũng không thể thấy nhiều sự kiện cảm ứng trên lớp phủ. Tôi có nghĩa là nếu bạn giữ ngón tay đầu tiên trên màn hình và sau đó thứ hai và sau đó thứ ba (mà không nâng những cái trước đó), chúng ta sẽ có thể nhận được các sự kiện liên lạc (tức là onTouch() nên được gọi). Có thể không? – Ravs

+0

Bạn sẽ không nhận được thông tin đa chạm khi ở trạng thái 'TYPE_SYSTEM_OVERLAY'. Khi bạn chuyển sang 'TYPE_SYSTEM_ALERT' (ví dụ: nhấc ngón tay lên sau khi nhấn bên trong lớp phủ), bạn sẽ nhận được các sự kiện đa chạm. Tôi nối thêm '\ nPOINTERS:" + event.getPointerCount() 'vào mỗi cuộc gọi' info.setText' trong mẫu của tôi và số đếm con trỏ sẽ tăng \ giảm khi tôi chạm vào \ nhấc ngón tay lên. Sau lần đầu tiên Tôi chỉ nhận được các sự kiện di chuyển, nhưng số lượng con trỏ vẫn thay đổi – jawsware

+1

Nhưng những gì tôi muốn thực sự nhận được đa cảm ứng với TYPE_SYSTEM_OVERLAY.Đó là có thể anyway? – Ravs

9

Bắt đầu từ Android 4.x, đội ngũ Android nhóm Android khắc phục sự cố an ninh tiềm năng bằng cách thêm một chức năng mới adjustWindowParamsLw() trong đó nó sẽ thêm FLAG_NOT_FOCUSABLE, FLAG_NOT_TOUCHABLE và loại bỏ cờ FLAG_WATCH_OUTSIDE_TOUCH cho cửa sổ TYPE_SYSTEM_OVERLAY.

Đó là cửa sổ TYPE_SYSTEM_OVERLAY sẽ không nhận được bất kỳ sự kiện chạm nào trên nền tảng ICS.

Cập nhật: 2016/5/4 TYPE_TOAST không thể nhận sự kiện chạm trên Android 4.0 ~ 4.3. Nó giống với TYPE_SYSTEM_OVERLAY. Trên Android 4.4 trở lên, TYPE_TOAST đã bị xóa khỏi danh sách bị loại trừ, vì vậy bạn có thể sử dụng TYPE_TOAST để nhận sự kiện chạm trên thiết bị Android 4.4 trở lên.

+1

Điều này hữu ích! Vì vậy, những gì bạn cho rằng tôi sử dụng thay vì FLAG_WATCH_OUTSIDE_TOUCH để đạt được chức năng tương tự trước khi Android 4.0. Có một lá cờ khác nên được thực hiện thay thế không? – Brian