Tap: nó là gì, xử lý chạm trong iOS và Android

Tác giả: IT Sectr Đã đăng: 2026-02-27 Thời gian đọc: 9 phút

Tap là cử chỉ cơ bản của giao diện cảm ứng: chạm một lần vào màn hình bằng ngón tay sau đó nhấc lên. Tap là hành động chính trong hệ điều hành di động — mở ứng dụng, nhấn nút, chọn mục danh sách. Nó được nhận dạng trong 100–300 ms và tạo ra sự kiện nhấp. Trên iOS, nó được xử lý qua UITapGestureRecognizer, trên Android — qua setOnClickListener hoặc View.onClick.

Những điểm chính

  • Cử chỉ cơ bản — Tap là cử chỉ nền tảng bắt đầu tương tác với giao diện cảm ứng
  • Hành động chính — Tap luôn thực hiện hành động chính: nhấn nút, mở liên kết, chọn phần tử
  • UITapGestureRecognizer — lớp chính của iOS để xử lý Tap với hỗ trợ đa chạm và nhiều lần chạm
  • setOnClickListener — phương thức chuẩn của Android để xử lý nhấp trên View
  • Độ trễ — Tap được nhận dạng trong 100–300 ms và không có thời gian chờ giữ

Tap là gì?

Tap (chạm, nhấn) là cử chỉ chạm nhanh vào màn hình cảm ứng bằng ngón tay hoặc bút stylus. Cử chỉ gồm hai giai đoạn: chạm xuống và nhấc lên, xảy ra tại cùng một vị trí mà không di chuyển. Hệ thống nhận dạng Tap khi khoảng thời gian giữa lúc chạm và nhấc không vượt quá giá trị ngưỡng (thường là 300–500 ms). Nếu người dùng giữ ngón tay lâu hơn — cử chỉ trở thành Nhấn giữ.

Tap là nền tảng của UX di động. Trên tất cả nền tảng di động, Tap thay thế nhấp chuột trái được sử dụng trong giao diện máy tính. Không giống như nhấp chuột, Tap không có bộ điều chỉnh (Shift+nhấp, Ctrl+nhấp) và không có di chuột — hạn chế này định hình thiết kế giao diện di động. Để bù đắp cho việc thiếu xem trước, nền tảng di động sử dụng phản hồi trực quan: làm nổi bật khi chạm, hiệu ứng gợn sóng trong Android, thay đổi độ trong suốt trong iOS.

Cấu trúc của Tap bao gồm năm giai đoạn ở cấp hệ thống: đánh thức cảm biến (chạm), xác định tọa độ, lọc nhiễu (ngón tay không được di chuyển quá khoảng cách ngưỡng), chờ hoàn thành (nhấc hoặc giữ), phân loại (Tap, Nhấn giữ, Kéo). Bộ điều khiển cảm ứng hiện đại xử lý chu trình này trong 8–16 ms ở tốc độ thăm dò 60–120 Hz.

Tap và Click: khác nhau thế nào?

Tap và Click là các sự kiện khác nhau với vật lý khác nhau. Click là sự kiện chuột xảy ra khi nhấn và thả nút chuột ở cùng một vị trí. Tap là sự kiện màn hình cảm ứng xảy ra khi ngón tay chạm vào. Trên thiết bị di động, trình duyệt chuyển đổi Tap thành sự kiện click với độ trễ 300–350 ms (để mô phỏng thu phóng chạm đôi). Độ trễ này từng là vấn đề lịch sử của web di động cho đến khi Apple và Google giới thiệu meta viewport với user-scalable=no.

Tham sốTap (cảm ứng)Click (chuột)
Thiết bị đầu vàoNgón tay, bút stylusCon trỏ chuột
Giai đoạntouchstart → touchendmousedown → mouseup
Xem trước (di chuột)Không cóCó (di chuột)
Độ trễ0–500 ms0 ms
Độ chính xácThấp (ngón tay rộng hơn con trỏ)Cao (cấp pixel)
Bộ điều chỉnhKhông cóShift, Ctrl, Cmd
Nhiều lầnĐa chạm (2+ ngón tay)Không (một con trỏ)

Touch Events là một API riêng biệt với Mouse Events. Sự kiện cảm ứng (touchstart, touchmove, touchend) truyền một mảng các điểm chạm (TouchList), tọa độ, áp lực và kích thước vùng chạm (radiusX, radiusY). Mouse Events chỉ truyền tọa độ con trỏ. Trình duyệt hiện đại tổng hợp click từ touchend nếu không có chuyển động ngón tay và không có sự kiện touchcancel. Pointer Events API kết hợp cả hai cách tiếp cận, cung cấp xử lý thống nhất cho tất cả thiết bị đầu vào.

Tap trong iOS: UITapGestureRecognizer

UITapGestureRecognizer là bộ nhận dạng tiêu chuẩn cho Tap đơn và nhiều lần trong iOS SDK. Hỗ trợ cấu hình numberOfTapsRequired (số lần chạm liên tiếp) và numberOfTouchesRequired (số ngón tay chạm đồng thời). Bộ nhận dạng chuyển sang trạng thái UIGestureRecognizerStateRecognized khi người dùng nhấc ngón tay và lần chạm không vượt quá ngưỡng di chuyển.

swift
// UITapGestureRecognizer hỗ trợ Double Tap
class InteractiveImageViewController: UIViewController {

    private var imageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Single Tap — hiển thị/ẩn điều khiển
        let singleTap = UITapGestureRecognizer(
            target: self,
            action: #selector(handleSingleTap)
        )
        imageView.addGestureRecognizer(singleTap)

        // Double Tap — phóng to hình ảnh
        let doubleTap = UITapGestureRecognizer(
            target: self,
            action: #selector(handleDoubleTap)
        )
        doubleTap.numberOfTapsRequired = 2

        // Single Tap chỉ kích hoạt nếu Double Tap không được nhận dạng
        singleTap.require(doubleTap.toFail())
        imageView.addGestureRecognizer(doubleTap)
    }

    @objc private func handleSingleTap() { /* hiển thị điều khiển */ }
    @objc private func handleDoubleTap() { /* thu phóng */ }
}

Mẫu quan trọng: khi hỗ trợ đồng thời Tap đơn và đôi, bạn phải gọi require(_:toFail:). Nếu không, tap đơn sẽ kích hoạt ngay lập tức, không cho hệ thống chờ lần nhấn thứ hai. iOS cũng hỗ trợ nhận dạng Tap qua UIControl.addTarget — cho UIButton, UISwitch và các điều khiển khác. Các điều khiển tích hợp sẵn của UIKit đã có xử lý Tap tiêu chuẩn, và thêm UITapGestureRecognizer lên chúng có thể gây xung đột.

Tap trong Android: setOnClickListener

View.setOnClickListener là phương thức tiêu chuẩn của Android SDK để xử lý nhấp trên View. Khi người dùng chạm vào View và nhấc ngón tay trên cùng một phần tử (touch down → touch up trong View), phương thức onClick() được gọi. Android tự động thêm hiệu ứng gợn sóng (trên API 21+) với hoạt ảnh chạm. Nút được coi là đã nhấn ở trạng thái PRESSED, được hiển thị trực quan qua bộ chọn hoặc RippleDrawable.

kotlin
// setOnClickListener trong Fragment với Data Binding
class ItemListFragment : Fragment() {

    private var binding: FragmentItemListBinding? = null

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding = FragmentItemListBinding.bind(view)
        binding.submitButton.setOnClickListener {
            submitForm()
        }

        // Trình lắng nghe debounce để ngăn nhấp đôi
        binding.submitButton.setOnClickListener(
            DebouncingClickListener {
                submitForm()
            }
        )
    }

    private fun submitForm() {
        // Gửi dữ liệu biểu mẫu
    }
}

Debounce là một mẫu quan trọng trong phát triển Android. Người dùng có thể vô tình nhấn nút hai lần trong thời gian ngắn, dẫn đến gửi biểu mẫu hai lần hoặc thực hiện hành động hai lần. Giải pháp: một wrapper DebouncingClickListener chặn các nhấp lặp lại trong 500–1000 ms. Google khuyến nghị cách tiếp cận này trong các ví dụ chính thức của Android Architecture Components. Cho RecyclerView, setOnItemClickListener được cung cấp qua ListAdapter với giao diện callback.

Chạm nhiều lần: Double Tap và Triple Tap

Double Tap (chạm đôi) — hai lần chạm liên tiếp với khoảng cách không quá 300–400 ms. Được sử dụng để phóng to hình ảnh (bản đồ, ảnh), thích trong mạng xã hội (Instagram, Twitter), quay lại đầu danh sách (Điện thoại, Tin nhắn). Triple Tap (chạm ba) ít phổ biến hơn — chủ yếu được sử dụng cho các chức năng trợ năng (chế độ toàn màn hình, VoiceOver) và trong trò chơi.

Triển khai Double Tap yêu cầu đồng bộ hóa với Tap đơn: nếu bạn thêm cả hai cử chỉ vào một phần tử, Tap đơn sẽ kích hoạt với độ trễ (hệ thống chờ lần nhấn thứ hai). Trong iOS, độ trễ này được quản lý qua require(toFail:) — Tap đơn bị hoãn lại cho đến khi chắc chắn rằng Double Tap sẽ không xảy ra. Trong Android, GestureDetector.OnDoubleTapListener được sử dụng với các callback onSingleTapConfirmed và onDoubleTap. onSingleTapConfirmed chỉ được gọi sau thời gian chờ khi hệ thống chắc chắn đó là một lần chạm đơn.

kotlin
// Double Tap trong Android qua GestureDetector
class PhotoViewerActivity : AppCompatActivity() {

    private var gestureDetector: GestureDetector? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        gestureDetector = GestureDetector(this, object : GestureDetector.SimpleOnGestureListener() {

            override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
                toggleControls() // hiển thị/ẩn điều khiển
                return true
            }

            override fun onDoubleTap(e: MotionEvent): Boolean {
                zoomToPoint(e.x, e.y) // phóng to tại điểm chạm
                return true
            }
        })
    }
}

Double tap kiểu Instagram là mẫu UX phổ biến cho ứng dụng xã hội. Chạm đôi vào ảnh kích hoạt hoạt ảnh thích (biểu tượng trái tim). Nó được triển khai qua GestureDetector trong Android hoặc UITapGestureRecognizer với numberOfTapsRequired=2 trong iOS. Cho hoạt ảnh, Core Animation được sử dụng trên iOS và ObjectAnimator/AnimatorSet trên Android. Thời gian phản hồi double tap phải tối thiểu — người dùng mong đợi hoạt ảnh ngay lập tức sau lần chạm thứ hai.

Nguyên tắc sử dụng Tap trong giao diện

Human Interface Guidelines của Apple và Material Design của Google có yêu cầu cụ thể cho Tap. Kích thước tối thiểu của mục tiêu chạm: 44×44 pt cho iOS và 48×48 dp cho Android. Điều này tương ứng với ~9 mm trên màn hình — kích thước đầu ngón tay của người trưởng thành trung bình. Khoảng cách giữa các mục tiêu chạm phải ít nhất 8 pt/dp để ngăn chạm nhầm.

Nguyên tắcGiá trịLý do
Kích thước tối thiểu mục tiêu44×44 pt (iOS) / 48×48 dp (Android)Kích thước đầu ngón tay trung bình ~9 mm
Khoảng cách giữa các mục tiêu≥8 pt / ≥8 dpNgăn chạm nhầm
Phản hồi trực quanLàm nổi bật / Gợn sóngXác nhận đăng ký chạm
Thời lượng hoạt ảnh chạm100–200 msĐủ để nhận biết, không làm chậm giao diện
Xử lý Double TapYêu cầu độ trễ Tap đơnNgăn kích hoạt nhầm
Vùng cạnh màn hìnhVùng va chạm mở rộngBù đắp cho cách cầm thiết bị

Phản hồi trực quan là bắt buộc cho Tap. Người dùng phải thấy rằng lần chạm đã được đăng ký: thay đổi màu sắc, độ trong suốt, hoạt ảnh gợn sóng hoặc làm nổi bật. Nếu không có phản hồi, người dùng có thể chạm lại, gây ra các hành động không mong muốn. Trong iOS, hoạt ảnh làm nổi bật chạm tiêu chuẩn là thay đổi độ trong suốt xuống 0.3 với thời gian 0.15 giây. Trong Android — hiệu ứng gợn sóng Material lan từ điểm chạm. Đừng trì hoãn phản hồi trực quan — người dùng sẽ thấy phản ứng đồng thời với lần chạm.

Câu hỏi thường gặp

Sự khác biệt giữa Tap và Click trong phát triển web là gì?

Tap là sự kiện cảm ứng, Click là sự kiện chuột. Trong trình duyệt, Tap được chuyển đổi thành Click với độ trễ 300 ms (để phân biệt với Thu phóng chạm đôi). Trình duyệt hiện đại (Chrome 32+, Safari 9.1+) tắt độ trễ này với meta viewport width=device-width. Sử dụng Pointer Events API để xử lý thống nhất: pointerdown/pointerup hoạt động cho tất cả thiết bị đầu vào (chuột, cảm ứng, bút stylus).

Kích thước nút tối thiểu cho Tap là bao nhiêu?

Mục tiêu chạm tối thiểu là 44×44 điểm (iOS) hoặc 48×48 dp (Android). Điều này tương ứng với khoảng 9×9 mm trên màn hình vật lý. Nếu nút nhỏ hơn về mặt trực quan (ví dụ: biểu tượng 24×24), hãy tăng vùng va chạm qua UIEdgeInsets (iOS) hoặc TouchDelegate (Android). Khoảng cách giữa các mục tiêu liền kề phải ít nhất 8 đơn vị để tránh chạm nhầm.

Làm thế nào để ngăn nhấp đôi vào nút?

Ngăn nhấp đôi được triển khai qua cơ chế debounce: sau lần nhấp đầu tiên, nút bị chặn trong 500–1000 ms. Trong Android, sử dụng DebouncingClickListener (giải pháp có sẵn từ Architecture Components). Trong iOS, vô hiệu hóa isEnabled của nút ngay sau khi nhấn và kích hoạt lại qua DispatchQueue.main.asyncAfter. Trong ứng dụng web, đặt cờ disabled trên phần tử button sau lần nhấp đầu tiên.

Long Tap là gì và khác với Tap thế nào?

Long Tap (Nhấn giữ) là giữ ngón tay trên màn hình 500+ ms mà không di chuyển. Tap là chạm nhanh (100–300 ms). Tap thực hiện hành động chính, Long Tap thực hiện hành động phụ (menu ngữ cảnh, chỉnh sửa). Trên iOS, Tap được xử lý bởi UITapGestureRecognizer, Nhấn giữ bởi UILongPressGestureRecognizer. Trên Android — setOnClickListener vs setOnLongClickListener.

Bút stylus Apple Pencil và S Pen có hỗ trợ Tap không?

Có, bút stylus được xử lý như Tap qua API cảm ứng tiêu chuẩn. Apple Pencil truyền lực (áp lực), altitudeAngle và azimuth. S Pen trong Android truyền các tham số tương tự qua MotionEvent.getPressure() và getAxisValue(MotionEvent.AXIS_TILT). Đối với bút stylus, bạn có thể giảm mục tiêu chạm xuống 24×24 điểm vì độ chính xác của bút cao hơn ngón tay.

Tóm tắt

  • Tap — cử chỉ chạm nhanh (100–300 ms), hành động chính của giao diện di động
  • Khác biệt với Nhấn giữ — Tap không có thời gian chờ giữ và thực hiện ngay lập tức
  • API iOS — UITapGestureRecognizer với numberOfTapsRequired và numberOfTouchesRequired
  • API Android — View.setOnClickListener và GestureDetector.OnDoubleTapListener
  • Double Tap — hai lần chạm liên tiếp với khoảng cách lên đến 400 ms để phóng to và thích
  • Mục tiêu chạm — kích thước mục tiêu tối thiểu 44×44 pt (iOS) hoặc 48×48 dp (Android)
  • Phản hồi trực quan — bắt buộc để xác nhận đăng ký chạm

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm