Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang
Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Khi vẽ, viết hoặc tương tác với ứng dụng bằng bút cảm ứng, đôi khi người dùng sẽ tì tay lên màn hình. Ứng dụng của bạn có thể sẽ nhận được báo cáo về sự kiện chạm trước khi hệ thống nhận ra và loại bỏ sự kiện đó dưới dạng thao tác vô tình tì tay.
Xác định và bỏ qua thao tác chạm bằng lòng bàn tay
Ứng dụng của bạn phải xác định các sự kiện chạm dư thừa và bỏ qua những sự kiện đó. Android huỷ thao tác tì tay bằng cách gửi một đối tượng MotionEvent đến ứng dụng của bạn.
Kiểm tra các đối tượng MotionEvent được gửi đến ứng dụng của bạn. Sử dụng các API MotionEvent để xác định các thuộc tính sự kiện (hành động và cờ):
Sự kiện chạm con trỏ một lần — Kiểm tra để tìm ACTION_CANCEL. Trên Android 13 trở lên, hãy kiểm tra để tìm cả FLAG_CANCELED.
Sự kiện chạm nhiều con trỏ – Trên Android 13 trở lên, hãy kiểm tra để tìm ACTION_POINTER_UP và FLAG_CANCELED.
Bỏ qua các sự kiện chuyển động có thuộc tính ACTION_CANCEL và ACTION_POINTER_UP/FLAG_CANCELED.
valmyView=findViewById<View>(R.id.myView).apply{setOnTouchListener{view,event->// Process motion event.}}
Java
ViewmyView=findViewById(R.id.myView);myView.setOnTouchListener((view,event)->{// Process motion event.});
2. Xác định thao tác và cờ cho sự kiện
Kiểm tra để tìm ACTION_CANCEL (cho biết sự kiện chạm con trỏ một lần ở mọi cấp độ API). Trên Android 13 trở lên, hãy kiểm tra ACTION_POINTER_UP để tìm FLAG_CANCELED.
Kotlin
valmyView=findViewById<View>(R.id.myView).apply{setOnTouchListener{view,event->when(event.actionMasked){MotionEvent.ACTION_CANCEL->{//Process canceled single-pointer motion event for all SDK versions.}MotionEvent.ACTION_POINTER_UP->{if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.TIRAMISU&&(event.flagsandMotionEvent.FLAG_CANCELED)==MotionEvent.FLAG_CANCELED){//Process canceled multi-pointer motion event for Android 13 and higher.}}}true}}
Java
ViewmyView=findViewById(R.id.myView);myView.setOnTouchListener((view,event)->{switch(event.getActionMasked()){caseMotionEvent.ACTION_CANCEL:// Process canceled single-pointer motion event for all SDK versions.caseMotionEvent.ACTION_UP:if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.TIRAMISU&&(event.getFlags()&MotionEvent.FLAG_CANCELED)==MotionEvent.FLAG_CANCELED){//Process canceled multi-pointer motion event for Android 13 and higher.}}returntrue;});
3. Huỷ cử chỉ
Sau khi xác định thấy thao tác tì tay, bạn có thể huỷ các hiệu ứng trên màn hình của cử chỉ.
ACTION_CANCEL: Hằng số MotionEvent cho biết cần huỷ một cử chỉ.
ACTION_POINTER_UP: Hằng số MotionEvent cho biết rằng con trỏ không phải là con trỏ đầu tiên đã dịch chuyển lên (nghĩa là con trỏ đã ngừng tiếp xúc với màn hình thiết bị).
FLAG_CANCELED: Hằng số MotionEvent cho biết rằng việc con trỏ dịch chuyển lên tạo ra một sự kiện chạm ngoài ý muốn. Đã thêm vào các sự kiện ACTION_POINTER_UP và ACTION_CANCEL trên Android 13 (API cấp 33) trở lên.
Kết quả
Giờ đây, ứng dụng của bạn có thể xác định và từ chối thao tác tì tay đối với các sự kiện chạm con trỏ nhiều lần ở những cấp độ API từ Android 13 trở lên và các sự kiện chạm con trỏ một lần ở mọi cấp độ API.
Các bộ sưu tập chứa hướng dẫn này
Hướng dẫn này là một phần của các bộ sưu tập Hướng dẫn nhanh được tuyển chọn này, bao gồm các mục tiêu phát triển Android rộng hơn:
Tối ưu hoá cho màn hình lớn
Cho phép ứng dụng của bạn hỗ trợ trải nghiệm người dùng được tối ưu hoá trên máy tính bảng, thiết bị có thể gập lại và thiết bị ChromeOS.
Nội dung và mã mẫu trên trang này phải tuân thủ các giấy phép như mô tả trong phần Giấy phép nội dung. Java và OpenJDK là nhãn hiệu hoặc nhãn hiệu đã đăng ký của Oracle và/hoặc đơn vị liên kết của Oracle.
Cập nhật lần gần đây nhất: 2025-02-06 UTC.
[[["Dễ hiểu","easyToUnderstand","thumb-up"],["Giúp tôi giải quyết được vấn đề","solvedMyProblem","thumb-up"],["Khác","otherUp","thumb-up"]],[["Thiếu thông tin tôi cần","missingTheInformationINeed","thumb-down"],["Quá phức tạp/quá nhiều bước","tooComplicatedTooManySteps","thumb-down"],["Đã lỗi thời","outOfDate","thumb-down"],["Vấn đề về bản dịch","translationIssue","thumb-down"],["Vấn đề về mẫu/mã","samplesCodeIssue","thumb-down"],["Khác","otherDown","thumb-down"]],["Cập nhật lần gần đây nhất: 2025-02-06 UTC."],[],[],null,["# Reject stylus palm touches\n\n\u003cbr /\u003e\n\nWhen users draw, write, or interact with an app using a stylus, they sometimes\ntouch the screen with the palm of their hands. The touch event might be reported\nto your app before the system recognizes and dismisses the event as an\naccidental palm touch.\n\nIdentify and ignore palm touches\n--------------------------------\n\nYour app must identify extraneous touch events and ignore them. Android cancels\na palm touch by dispatching a [`MotionEvent`](/reference/kotlin/android/view/MotionEvent) object to your app.\n\n- Examine `MotionEvent` objects dispatched to your app. Use the `MotionEvent`\n APIs to determine event properties (actions and flags):\n\n - **Single-pointer events** --- Check for [`ACTION_CANCEL`](/reference/kotlin/android/view/MotionEvent#action_cancel). On Android 13 and higher, also check for [`FLAG_CANCELED`](/reference/kotlin/android/view/MotionEvent#flag_canceled).\n - **Multi-pointer events** --- On Android 13 and higher, check for [`ACTION_POINTER_UP`](/reference/kotlin/android/view/MotionEvent#action_pointer_up) and `FLAG_CANCELED`.\n- Ignore motion events that have the `ACTION_CANCEL` and\n `ACTION_POINTER_UP`/`FLAG_CANCELED` properties.\n\n| **Warning:** Android 12 (API level 32) and lower provide only `ACTION_POINTER_UP` for non-primary multi-pointer events. `FLAG_CANCELED` is not set for cancelable events such as palm touches. As a result, apps cannot determine whether the touch was intended or not on Android 12 and lower.\n\n### 1. Acquire motion event objects\n\nAdd an [`OnTouchListener`](/reference/kotlin/android/view/View.OnTouchListener) to your app: \n\n### Kotlin\n\n```kotlin\nval myView = findViewById\u003cView\u003e(R.id.myView).apply {\n setOnTouchListener { view, event -\u003e\n // Process motion event.\n }\n}\n```\n\n### Java\n\n```java\nView myView = findViewById(R.id.myView);\nmyView.setOnTouchListener( (view, event) -\u003e {\n // Process motion event.\n});\n```\n\n### 2. Determine the event action and flags\n\nCheck for `ACTION_CANCEL`, which indicates a single-pointer event on all API\nlevels. On Android 13 and higher, check `ACTION_POINTER_UP` for `FLAG_CANCELED.` \n\n### Kotlin\n\n```kotlin\nval myView = findViewById\u003cView\u003e(R.id.myView).apply {\n setOnTouchListener { view, event -\u003e\n when (event.actionMasked) {\n MotionEvent.ACTION_CANCEL -\u003e {\n //Process canceled single-pointer motion event for all SDK versions.\n }\n MotionEvent.ACTION_POINTER_UP -\u003e {\n if (Build.VERSION.SDK_INT \u003e= Build.VERSION_CODES.TIRAMISU &&\n (event.flags and MotionEvent.FLAG_CANCELED) == MotionEvent.FLAG_CANCELED) {\n //Process canceled multi-pointer motion event for Android 13 and higher.\n }\n }\n }\n true\n }\n}\n```\n\n### Java\n\n```java\nView myView = findViewById(R.id.myView);\nmyView.setOnTouchListener( (view, event) -\u003e {\n switch (event.getActionMasked()) {\n case MotionEvent.ACTION_CANCEL:\n // Process canceled single-pointer motion event for all SDK versions.\n case MotionEvent.ACTION_UP:\n if (Build.VERSION.SDK_INT \u003e= Build.VERSION_CODES.TIRAMISU &&\n (event.getFlags() & MotionEvent.FLAG_CANCELED) == MotionEvent.FLAG_CANCELED) {\n //Process canceled multi-pointer motion event for Android 13 and higher.\n }\n }\n return true;\n});\n```\n\n### 3. Undo the gesture\n\nAfter you've identified a palm touch, you can undo the onscreen effects of the\ngesture.\n\nYour app must keep a history of user actions so that unintended inputs such as\npalm touches can be undone. For an example of how to maintain history, see\n[Implement a basic drawing app](/codelabs/large-screens/advanced-stylus-support#2) in the [Enhance stylus support in an Android\napp](/codelabs/large-screens/advanced-stylus-support) codelab.\n\nKey points\n----------\n\n- [`MotionEvent`](/reference/kotlin/android/view/MotionEvent): Represents touch and movement events. Contains the information necessary to determine whether an event should be disregarded.\n- [`OnTouchListener#onTouch()`](/reference/kotlin/android/view/View.OnTouchListener#ontouch): Receives `MotionEvent` objects.\n- [`MotionEvent#getActionMasked()`](/reference/kotlin/android/view/MotionEvent#getactionmasked): Returns the action associated with a motion event.\n- [`ACTION_CANCEL`](/reference/kotlin/android/view/MotionEvent#action_cancel): `MotionEvent` constant that indicates a gesture should be undone.\n- [`ACTION_POINTER_UP`](/reference/kotlin/android/view/MotionEvent#action_pointer_up): `MotionEvent` constant that indicates a pointer other than the first pointer has gone up (that is, has relinquished contact with the device screen).\n- [`FLAG_CANCELED`](/reference/kotlin/android/view/MotionEvent#flag_canceled): `MotionEvent` constant that indicates that the pointer going up caused an unintentional touch event. Added to `ACTION_POINTER_UP` and `ACTION_CANCEL` events on Android 13 (API level 33) and higher.\n\nResults\n-------\n\nYour app can now identify and reject palm touches for multi-pointer events on\nAndroid 13 and higher API levels and for single-pointer events on all API\nlevels.\n\nCollections that contain this guide\n-----------------------------------\n\nThis guide is part of these curated Quick Guide collections that cover\nbroader Android development goals: \n\n### Optimize for large screens\n\nEnable your app to support an optimized user experience on tablets, foldables, and ChromeOS devices. \n[Quick guide collection](/quick-guides/collections/optimize-for-large-screens) \n\nHave questions or feedback\n--------------------------\n\nGo to our frequently asked questions page and learn about quick guides or reach out and let us know your thoughts. \n[Go to FAQ](/quick-guides/faq) [Leave feedback](https://issuetracker.google.com/issues/new?component=1573691&template=1993320)"]]