2012-11-25 43 views

Trả lời

0

Thực hiện Pinch zoom Gesture

Các nhúm zoom cử chỉ tương tự như các cử chỉ kéo, ngoại trừ nó bắt đầu khi các ngón tay thứ hai được nhấn vào màn hình (ACTION_POINTER_DOWN).

 
case MotionEvent.ACTION_POINTER_DOWN: 
oldDist = spacing(event); 
Log.d(TAG, "oldDist=" + oldDist); 
if (oldDist > 10f) { 
savedMatrix.set(matrix); 
midPoint(mid, event); 
mode = ZOOM; 
Log.d(TAG, "mode=ZOOM"); 
} 
break; 


case MotionEvent.ACTION_MOVE: 
if (mode == DRAG) { 
// ... 
} 
else if (mode == ZOOM) { 
float newDist = spacing(event); 
Log.d(TAG, "newDist=" + newDist); 
if (newDist > 10f) { 
matrix.set(savedMatrix); 
float scale = newDist/oldDist; 
matrix.postScale(scale, scale, mid.x, mid.y); 
} 
} 
break; 

Khi chúng tôi nhận sự kiện xuống cho ngón tay thứ hai, chúng tôi tính toán và nhớ khoảng cách giữa hai ngón tay. Trong thử nghiệm của tôi, Android đôi khi sẽ cho tôi biết (không chính xác) rằng có hai ngón tay ấn xuống ở gần như chính xác cùng một vị trí. Vì vậy, tôi đã thêm một dấu kiểm để bỏ qua sự kiện nếu khoảng cách nhỏ hơn một số pixel tùy ý. Nếu lớn hơn thế, chúng ta nhớ ma trận chuyển đổi hiện tại, tính điểm giữa của hai ngón tay và bắt đầu thu phóng.

Khi sự kiện di chuyển đến khi chúng tôi đang ở chế độ thu phóng, chúng tôi tính khoảng cách giữa các ngón tay một lần nữa. Nếu nó quá nhỏ, sự kiện sẽ bị bỏ qua, nếu không chúng tôi sẽ khôi phục ma trận chuyển đổi và chia tỷ lệ hình ảnh xung quanh điểm giữa.

Tỷ lệ chỉ đơn giản là tỷ lệ của khoảng cách mới chia cho khoảng cách cũ. Nếu khoảng cách mới lớn hơn (nghĩa là, các ngón tay đã tách xa nhau), thì tỷ lệ sẽ lớn hơn 1, làm cho hình ảnh lớn hơn. Nếu nó nhỏ hơn (ngón tay gần nhau hơn), thì tỷ lệ sẽ nhỏ hơn một, làm cho hình ảnh nhỏ hơn. Và tất nhiên nếu mọi thứ đều giống nhau, tỷ lệ bằng 1 và hình ảnh không bị thay đổi.

Bây giờ, hãy xác định phương thức khoảng cách() và midPoint().

Khỏang cách giữa hai điểm

Để tìm hiểu cách xa nhau hai ngón tay là, đầu tiên chúng ta xây dựng một vector (x, y) là phần chênh lệch giữa hai điểm.

Sau đó, chúng tôi sử dụng công thức cho khoảng cách Euclide để tính toán khoảng cách:

 
private float spacing(MotionEvent event) { 
float x = event.getX(0) - event.getX(1); 
float y = event.getY(0) - event.getY(1); 
return FloatMath.sqrt(x * x + y * y); 
} 

Thứ tự của các điểm không quan trọng bởi vì bất kỳ dấu hiệu tiêu cực sẽ bị mất khi chúng vuông họ. Lưu ý rằng tất cả toán học được thực hiện bằng cách sử dụng loại phao của Java. Mặc dù một số thiết bị Android có thể không có phần cứng dấu chấm động nhưng chúng tôi không thực hiện việc này thường xuyên đủ để lo lắng về hiệu suất của thiết bị.

Midpoint of Two Điểm

Tính toán một điểm ở giữa hai điểm thậm chí còn dễ dàng hơn:

 
private void midPoint(PointF point, MotionEvent event) { 
float x = event.getX(0) + event.getX(1); 
float y = event.getY(0) + event.getY(1); 
point.set(x/2, y/2); 
} 

Tất cả chúng tôi làm là lấy trung bình của X và Y tọa độ của họ. Để tránh các bộ sưu tập rác có thể gây ra tạm dừng đáng chú ý trong ứng dụng, chúng tôi sử dụng lại một đối tượng hiện có để lưu trữ kết quả thay vì phân bổ và trả lại một kết quả mới mỗi lần. Thử chạy chương trình ngay trên điện thoại của bạn. Kéo hình ảnh bằng một ngón tay và thu phóng bằng cách véo hai ngón tay vào hoặc ra. Để có kết quả tốt nhất, đừng để ngón tay của bạn tiến gần hơn một inch hoặc xa nhau. Nếu không, bạn sẽ bắt đầu chạy vào một số lỗi trong API mà tôi đã đề cập trước đó.

This is an excerpt from Hello, Android 3rd edition, published by the Pragmatic Bookshelf. For more information or to purchase a paperback or PDF copy, please visit http://www.pragprog.com/titles/eband3

Các vấn đề liên quan