Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wordpress-seo domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /var/www/vinascript/html/wp-includes/functions.php on line 6114
Xử lý đa chạm Multi Touch trong Android - VinaScript

Latest Post

Triển khai dự án PHP, Mysql với Nginx trên Docker Tìm hiểu về HTML – Ưu điểm, nhược điểm và cách hoạt động của HTML
Multi touch trong Android
Multi touch trong Android

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.

Đâ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 đó.

#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é.

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *