Xử lý đa chạm Multi Touch trong Android

Dịch vụ dạy kèm gia sư lập trình

Hầu hết các thiết bị Android bây giờ đang dùng màn hình hỗ trợ cảm ứng đa điểm. Việc phát hiện ra các vị trí touch (sự kiện chạm cảm ứng vào màn hình) hay gọi là multi touch. Multi touch trong Android là một tính năng rất hay, với nhiều ứng dụng trong thực tế.

Multi touch trong android giúp chúng ta biết được vị trí ngón tay thao tác. Từ đó giúp chúng ta tuỳ chỉnh theo yêu cầu của bài toán ứng dụng. Ví dụ như tính năng Zoom trong ứng dụng Gallery.

Bài viết này, mình sẽ hướng dẫn các bạn về xử lý Multi Touch để zoom ảnh trong ứng dụng Gallery.

Hướng dẫn viết code xử lý Multi touch trong Android

Ở bài viết viết này, mình sẽ hướng dẫn các bạn zoom ảnh bằng 2 ngón tay trong android.

Bản chất multi touch vẫn là xử lý sự kiện chạm vào màn hình cảm ứng, chỉ khác là dùng một ngón thì multi touch sẽ dùng nhiều ngón tay. Vì vậy, để hiển thị ảnh thì mình phải sử dụng một view nào đó như ImageView.

Tuy nhiên, ImageView theo mặc định thì lại không hỗ trợ multi touch. Đó là lý do mình sẽ tạo một custom view để build một view hiển thị ảnh có hỗ trợ multi touch.

👏 Bạn có thể đọc thêm về cách tạo một custom view cơ bản tại đây: Hướng dẫn tạo Custom View trong Android cho người mới

Đây là giao diện ứng dụng sau khi hoàn thành bài viết này. Nhìn giao diện rất cơ bản phải không?

Các sử dụng ứng dụng là bạn dụng 2 ngón tay để có thể zoom to nhỏ ảnh.

#1. Tạo một custom view

Đầu tiên các bạn tạo class ZoomImageView kế thừa từ ImageView để chúng ta bắt đầu customView.

public class ZoomImageView extends ImageView {
    public ZoomImageView(Context context) {
        super(context);
    }

    public ZoomImageView(Context context,  AttributeSet attrs) {
        super(context, attrs);
    }

    public ZoomImageView(Context context,  AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @SuppressLint("NewApi")
    public ZoomImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }
}

Android cung cấp lớp MotionEvent để hỗ trợ cảm ứng khi người dùng chạm vào màn hình thông qua view với phương thức onTouch().

Bạn chỉ cần overide lại phương thức onTouch() đối với view mà bạn muốn.

#2. Tìm hiểu hàm onTouch()

Lớp MotionEvent chứa các thông tin liên quan như: số lượng con trỏ, tọa độ X / Y, kích thước và áp lực của mỗi con trỏ.

@Override
public boolean onTouch(View v, MotionEvent event) {
    if (mGestureDetector.onTouchEvent(event)) return true;
    mScaleGestureDetetor.onTouchEvent(event);
    float x = 0;
    float y = 0;
    int pointCount = event.getPointerCount();
    for (int i = 0; i < pointCount; i++) {
        x = x + event.getX(i);
        y = y + event.getY(i);
    }
    x /= pointCount;
    y /= pointCount;

    if (mLastPointCount != pointCount) {
        isCanDrag = false;
        mLastX = x;
        mLastY = y;
    }
    mLastPointCount = pointCount;
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            break;
        case MotionEvent.ACTION_MOVE:
            float dx = x - mLastX;
            float dy = y - mLastY;
            if (!isCanDrag) {
                isCanDrag = isMoveAction(dx, dy);
            }
            if (isCanDrag) {
                RectF rectF = getMatrixRectF();
                if (getDrawable() != null) {
                    if (rectF.width() < getWidth()) {
                        dx = 0;
                    }
                    if (rectF.height() < getHeight()) {
                        dy = 0;
                    }
                    mMatrix.postTranslate(dx, dy);
                    checkBorderAndCenterWhenScale();
                    setImageMatrix(mMatrix);
                }
            }
            mLastX = x;
            mLastY = y;
            break;
        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP:
            mLastPointCount = 0;
            break;
    }
    return true;
}

Giống như các sự kiện khác, sự kiện Touch của một view có thể được phát hiện và xử lý thông qua việc đăng ký với trình lắng nghe sự kiện onTouchListener và thực thi phương thức onTouch() tương ứng.

Các phương thức onTouch trả về giá trị true nếu người dùng nhấn xuống hoặc nâng lên để chỉ ra rằng nó đã tiêu thụ các sự kiện. Tuy nhiên, đối với tất cả các hành động cảm ứng khác, phương thức này trả về giá trị false để chỉ ra rằng nó đã không nhận các sự kiện và các yếu tố khác có thể tiếp tục xử lý sự kiện này.

Khi xảy ra nhiều lần chạm vào màn hình tại cùng một thời điểm, mỗi một lần chạm được xem như là một con trỏ (pointer).

Mỗi con trỏ sẽ được tham chiếu đến một index và được gán một ID. Số con trỏ hay số lần chạm có thể được xác định nhờ phương thức getPointerCount() của đối tượng MotionEvent.

Giá trị trả về của hàm onTouch()

  • MotionEvent.ACTION_DOWN : Trả về với sự kiện khi bạn bắt đầu chạm vào view
  • MotionEvent.ACTION_MOVE : Trả về khi bạn di chuyển trên view đó.
  • MotionEvent.ACTION_UP : Trả về khi bạn nhấc tay ra khỏi view.
  • MotionEvent.ACTION_CANCEL : Trả về khi event touch cancel.
  • MotionEvent.ACTION_POINTER_DOWN : Chỉ có với multi-touch, trả về vị trí của mới khi bạn multiple touch
  • MotionEvent.ACTION_POINTER_UP : Chỉ có với multi-touch, trả ra khi bạn cancel một điểm mà bạn đã chạm trước đó.

💦 Bài viết khác có ích cho bạn: Xử lý sự kiện trong Android (Event Listeners)

#3. Xử lý scale ảnh khi phát hiện Multi touch trong android

Để scale được hình ảnh các bạn  kế thừa từ lớp ScaleGestureDetector.

public class ZoomImageView extends ImageView implements View.OnTouchListener, ScaleGestureDetector.OnScaleGestureListener

và chúng ta sẽ viết các tính toán trong hàm onScall().

@Override
public boolean onScale(ScaleGestureDetector detector) {
    float scale = getScale();
    float factor = detector.getScaleFactor();

    if (getDrawable() == null) return true;

    float dx = detector.getFocusX();
    float dy = detector.getFocusY();

    if ((scale < mMaxScale && factor > 1.0) || (scale > mInitScale && factor < 1.0f)) {
        if (scale * factor < mInitScale) {
            factor = mInitScale / scale;
        }

        if (scale * factor > mMaxScale) {
            factor = mMaxScale / scale;
        }

        mMatrix.postScale(factor, factor, dx, dy);

        checkBorderAndCenterWhenScale();

        setImageMatrix(mMatrix);
    }
    return true;
}

#4. Sử dụng ZoomImageView

Cuối cùng chúng ta chỉ cần khai báo trong file xml, giống bài trước mình đã hướng dẫn các bạn custom 1 view là xong và run project là chạy.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.example.zoomimageview.ZoomImageView
        android:id="@+id/action_infolinks_splash"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:src="@mipmap/bg_sontung" />

</LinearLayout>

Tổng kết

Như vậy là chúng ta đã hoàn thành việc tạo một custom view có hỗ trợ multi touch trong android.

Các bạn có thể download toàn bộ source code của bài hướng dẫn tại đây nhé.

Hy vọng bài viết này sẽ giúp bạn phần nào hiểu và có thể tự xử lý MultiTouch  cho ứng dụng của mình.

Ứng dụng của bạn có sử dụng Multi touch không? Để lại ý kiến của bạn ở bên dưới nhé.

Dịch vụ phát triển ứng dụng mobile giá rẻ - chất lượng
Bài trướcKotlin trên Android – từ cơ bản tới nâng cao
Bài tiếp theoHeadless CMS là gì? Có nên quan tâm tới Headless CMS lúc này?
Tất cả lập trình viên đều là những nhà viết kịch và tất cả máy tính đều là những diễn viên tồi.

20
Bình luận. Cùng nhau thảo luận nhé!

avatar
  Theo dõi bình luận  
Mới nhất Cũ nhất Nhiều voted nhất
Thông báo
BillieOntok
Guest
BillieOntok

Invite friends to solve puzzles
Win NFTs and $500,000

Williamthali
Guest
Williamthali

А тут читатели выбирают все самое любимое. После окончания обучения можно найти работу в центре магии и парапсихологии или эзотерическом салоне. Есть возможность вести частную практику онлайн и оффлайн. Также данная книга доступна ещё в библиотеке. Запишись сразу в несколько библиотек и получай книги намного быстрее. Сергей Mannara 11 минут назад. Москва, ул. Лесная, 13. Главное 2024 Все книги Билингвы Назад в «Книги» Все книги в жанре «Билингвы» Все книги жанра Билингвы для детей Билингвы. Английский язык Билингвы. Другие языки Билингвы. Испанский язык Билингвы. Итальянский язык Билингвы. Немецкий язык Билингвы. Французский язык Назад в «Книги» Все книги в жанре «Книги… Đọc thêm »

Leupoldlpi
Guest
Leupoldlpi

From many manuscripts of Antiquity

PeterNaith
Guest
PeterNaith

Проведенные исследования показывают, что психологическое состояние человека может оказывать влияние на его успех в бизнесе. Магические практики, такие как заговоры, могут стать эффективным инструментом для изменения этого состояния. Заказав заговор на хорошую торговлю у Романа Петровича на сайте nfkts545.ru (ватсап 8 (984) 286-12-65), я убедился в этом на собственном опыте. -мощный заговор на торговлю – списки настоящих магов -заговор на торговлю читать на рабочем – проверенные маги хабаровска 89842861265 -заговор на торговлю читать на рабочем – мощный заговор на удачную торговлю nfkts545.ru -на быструю торговлю заговор -срочный заговор на торговлю -срочный заговор на торговлю -заговоры на хорошую торговлю для продавца… Đọc thêm »

StevenBix
Guest
StevenBix

маг иннер отзывы Copyright (с) ООО «Шкулёв Диджитал Технологии», 2024. Любое воспроизведение материалов сайта без разрешения редакции воспрещается.Мама дорогая,вам в дурку надо,и всем остальным кто в это верит тоже.Приворот и порча это разные вещи. А у вас невроз походу. Надо хорошего психотерапевта. У приворота другие симптомы. А если порча, то надо к проведенному человеку идти, а то разведут на деньги. Ее можно самой проверить.Выражается порча в резких неприятных переменах, в серьезных проблемах со здоровьем, в разрушении отношений с окружающими, а также в депрессиях, в суицидальных наклонностях и в невозможности противостоять неблагоприятным обстоятельствам. Иногда, если наведенная порча очень сильна, то страдает… Đọc thêm »

JasonSup
Guest
JasonSup

альмарель маг отзывы андрей 17.11.2015 19:50 Хотим с женой сказать спасибо большое гинекологии. очень чуткие доктора,настоящие профессионалы своего дела. отдельное спасибо заведующей гинекологии Князевой Наталье Александровне! Огромное спасибо всем докторам. MatthewNuapy disse: Для этого наговора-приворота нужна вода, освященная в церкви. Очень сильным получится наговор, если набрать воду в ночь на Крещение Господне. Приворот на сигарете. Как сделать приворот на сигарете. Как приворожить человека при помощи сигареты. Самый простой приворот который можно сделать самостоятельно это приворот на сигарете. Курящему человеку дать сигарету на которую сделан приворотный обряд не составит особого труда. Сигарета на которую читали приворот ничем не отличается от 100… Đọc thêm »

Kellycal
Guest
Kellycal

lolita cp

==> 88nb.cc/aesiz url.epoch.tw/ZxQgz <==

lolita cp

Jamespog
Guest
Jamespog

Я хочу поделиться своим опытом использования услуг частного специалиста по озонированию, которого я нашла по номеру 8 909 826 3556 (Комсомольск-на-Амуре), для решения проблемы с запахом пота в фитнес зале, где я тренируюсь регулярно. Несмотря на то, что администрация зала предпринимала меры для борьбы с этим запахом, он продолжал оставаться и мешать моему комфорту во время тренировок. После того, как я нашла контактный номер частного специалиста по озонированию, я решила связаться с ним и узнать, сможет ли он помочь в решении моей проблемы. С первого же звонка я почувствовала, что имею дело с профессионалом, который понимает, как важно избавиться от… Đọc thêm »

TriptiaWap
Guest
TriptiaWap

Have you ever considered about including a little bit more than just your articles? I mean, what you say is fundamental and all. Nevertheless think of if you added some great graphics or videos to give your posts more, “pop”! Your content is excellent but with pics and video clips, this website could certainly be one of the most beneficial in its field. Good blog!

Brianlal
Guest
Brianlal

SEO-Ezoterica ru использует передовые технологии в управлении онлайн-репутацией. Их методы действенны и результативны!