Android 實現圖片縮放和拖動
今天我們來編寫一個縮放效果的ImageView ,網上有很多人都講了這些。但有許多人都直接使用了庫檔案,
那麼我們今天做的是直接上程式碼編寫一個拖動和縮放的ImageView,具體看效果圖,
那麼簡單了分析一下。在手機上縮放圖片和拖動要用到什麼?手指對不對
那麼控制元件上什麼事件和手機有關。View.OnTouchListener 對不對。
ok,那麼先新建一個Class
···
public class BaseDragZoomImageView extends ImageView implements View.OnTouchListener
···
沒錯,繼承ImageView 並且新增View.OnTouchListener事件
然後我們看看建構函式
public BaseDragZoomImageView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
setOnTouchListener(this);
}
public BaseDragZoomImageView(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
setOnTouchListener(this );
}
public BaseDragZoomImageView(Context context)
{
this(context, null);
setOnTouchListener(this);
}
對,在建構函式中,我們將setOnTouchListener 設定了。
那麼這個setOnTouchListener 具體怎麼做。我們就先分析一下onTouch 中MotionEvent。
我們都知道手指的操作有很多,那麼Andorid自然也將這種情況分了很多種case。
- MotionEvent.ACTION_DOWN 手指按下螢幕
- MotionEvent.ACTION_MOVE 手指在螢幕上移動
- MotionEvent.ACTION_UP 手指離開螢幕
- MotionEvent.ACTION_POINTER_UP 當觸點離開螢幕,但是螢幕上還有觸點(手指)
- MotionEvent.ACTION_POINTER_DOWN 當螢幕上已經有觸點(手指),再有一個觸點壓下螢幕
很顯然,這些看起來好像都能夠用得到。
public boolean onTouch(View v, MotionEvent event) {
/** 通過與運算保留最後八位 MotionEvent.ACTION_MASK = 255 */
switch (event.getAction() & MotionEvent.ACTION_MASK) {
// 手指壓下螢幕
case MotionEvent.ACTION_DOWN:
mode = MODE_DRAG;
// 記錄ImageView當前的移動位置
currentMatrix.set(getImageMatrix());
startPoint.set(event.getX(), event.getY());
break;
// 手指在螢幕上移動,改事件會被不斷觸發
case MotionEvent.ACTION_MOVE:
// 拖拉圖片
if (mode == MODE_DRAG) {
float dx = event.getX() - startPoint.x; // 得到x軸的移動距離
float dy = event.getY() - startPoint.y; // 得到x軸的移動距離
// 在沒有移動之前的位置上進行移動
matrix.set(currentMatrix);
matrix.postTranslate(dx, dy);
}
// 放大縮小圖片
else if (mode == MODE_ZOOM) {
float endDis = distance(event);// 結束距離
if (endDis > 10f) { // 兩個手指併攏在一起的時候畫素大於10
float scale = endDis / startDis;// 得到縮放倍數
matrix.set(currentMatrix);
matrix.postScale(scale, scale,midPoint.x,midPoint.y);
}
}
break;
// 手指離開螢幕
case MotionEvent.ACTION_UP:
// 當觸點離開螢幕,但是螢幕上還有觸點(手指)
case MotionEvent.ACTION_POINTER_UP:
mode = 0;
break;
// 當螢幕上已經有觸點(手指),再有一個觸點壓下螢幕
case MotionEvent.ACTION_POINTER_DOWN:
mode = MODE_ZOOM;
/** 計算兩個手指間的距離 */
startDis = distance(event);
/** 計算兩個手指間的中間點 */
if (startDis > 10f) { // 兩個手指併攏在一起的時候畫素大於10
midPoint = mid(event);
//記錄當前ImageView的縮放倍數
currentMatrix.set(getImageMatrix());
}
break;
}
setImageMatrix(matrix);
return true;
}
ok,收工。具體就只有這麼多。我們來看下整個class
package com.jonkming.easyui.image.dragzoom.ui;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.util.FloatMath;
/**
* 圖片縮放和拖動類
* @Title: BaseDragZoomImageView.java
* @Package com.jonkming.easyui.image.dragzoom.ui
* @author HuangMingming
* @date 2016/11/7 17:40
* @version V1.0
*/
public class BaseDragZoomImageView extends ImageView implements View.OnTouchListener{
/** 記錄是拖拉照片模式還是放大縮小照片模式 */
private int mode = 0;// 初始狀態
/** 拖拉照片模式 */
private static final int MODE_DRAG = 1;
/** 放大縮小照片模式 */
private static final int MODE_ZOOM = 2;
/** 用於記錄開始時候的座標位置 */
private PointF startPoint = new PointF();
/** 用於記錄拖拉圖片移動的座標位置 */
private Matrix matrix = new Matrix();
/** 用於記錄圖片要進行拖拉時候的座標位置 */
private Matrix currentMatrix = new Matrix();
/** 兩個手指的開始距離 */
private float startDis;
/** 兩個手指的中間點 */
private PointF midPoint;
public BaseDragZoomImageView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
setOnTouchListener(this);
}
public BaseDragZoomImageView(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
setOnTouchListener(this);
}
public BaseDragZoomImageView(Context context)
{
this(context, null);
setOnTouchListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
/** 通過與運算保留最後八位 MotionEvent.ACTION_MASK = 255 */
switch (event.getAction() & MotionEvent.ACTION_MASK) {
// 手指壓下螢幕
case MotionEvent.ACTION_DOWN:
mode = MODE_DRAG;
// 記錄ImageView當前的移動位置
currentMatrix.set(getImageMatrix());
startPoint.set(event.getX(), event.getY());
break;
// 手指在螢幕上移動,改事件會被不斷觸發
case MotionEvent.ACTION_MOVE:
// 拖拉圖片
if (mode == MODE_DRAG) {
float dx = event.getX() - startPoint.x; // 得到x軸的移動距離
float dy = event.getY() - startPoint.y; // 得到x軸的移動距離
// 在沒有移動之前的位置上進行移動
matrix.set(currentMatrix);
matrix.postTranslate(dx, dy);
}
// 放大縮小圖片
else if (mode == MODE_ZOOM) {
float endDis = distance(event);// 結束距離
if (endDis > 10f) { // 兩個手指併攏在一起的時候畫素大於10
float scale = endDis / startDis;// 得到縮放倍數
matrix.set(currentMatrix);
matrix.postScale(scale, scale,midPoint.x,midPoint.y);
}
}
break;
// 手指離開螢幕
case MotionEvent.ACTION_UP:
// 當觸點離開螢幕,但是螢幕上還有觸點(手指)
case MotionEvent.ACTION_POINTER_UP:
mode = 0;
break;
// 當螢幕上已經有觸點(手指),再有一個觸點壓下螢幕
case MotionEvent.ACTION_POINTER_DOWN:
mode = MODE_ZOOM;
/** 計算兩個手指間的距離 */
startDis = distance(event);
/** 計算兩個手指間的中間點 */
if (startDis > 10f) { // 兩個手指併攏在一起的時候畫素大於10
midPoint = mid(event);
//記錄當前ImageView的縮放倍數
currentMatrix.set(getImageMatrix());
}
break;
}
setImageMatrix(matrix);
return true;
}
/** 計算兩個手指間的距離 */
private float distance(MotionEvent event) {
float dx = event.getX(1) - event.getX(0);
float dy = event.getY(1) - event.getY(0);
/** 使用勾股定理返回兩點之間的距離 */
return (float) Math.sqrt(dx * dx + dy * dy);
}
/** 計算兩個手指間的中間點 */
private PointF mid(MotionEvent event) {
float midX = (event.getX(1) + event.getX(0)) / 2;
float midY = (event.getY(1) + event.getY(0)) / 2;
return new PointF(midX, midY);
}
}
然後看佈局檔案
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<com.jonkming.easyui.image.dragzoom.ui.BaseDragZoomImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/dragandzoombase"
android:scaleType="matrix"
/>
</LinearLayout>
就是這麼簡單。
相關推薦
Android 實現圖片縮放和拖動
今天我們來編寫一個縮放效果的ImageView ,網上有很多人都講了這些。但有許多人都直接使用了庫檔案, 那麼我們今天做的是直接上程式碼編寫一個拖動和縮放的ImageView,具體看效果圖, 那麼簡單了分析一下。在手機上縮放圖片和拖動要用到什麼?手指對不
Android自定義imageview可對圖片進行多點縮放和拖動
package com.msstudent.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import andro
【EasyAR學習】縮放和拖動模型
開發AR手機端軟體時,雙手縮放、拖動模型是最常見的功能,也是一種最基本的互動手段。 在 Unity 中想要獲取使用者的鍵盤或滑鼠的事件的話,就必須使用 Input 類來獲取。一般來說 Input 類的方法需要寫在 Update() 方法中。
android實現圖片縮放、移動、單擊退出、雙擊縮放
實現思路 思路:重寫用於顯示圖片的ImageView,定義ScaleGestureDetector(縮放手勢檢測)型別、GestureDetector(雙擊手勢檢測)型別的變數進行手勢檢測並重寫方法實現圖片的縮放、移動、單擊退出、雙擊放大等功能。 重
surfaceView實現圖片縮放拖動功能
還是老闆牛,多向他學習請教。之前折騰了好一會兒的問題,被老闆一上午搞定。 問題:採用surface來實現多點觸控縮放,拖動顯示功能。 附上初稿程式碼,明天再好好整理下, public class MySurfaceView3 extends SurfaceView impl
C#實現圖片縮放(包括縮圖和旋轉)
using System; using System.Collections; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Web; using Syst
flutter實現可縮放可拖拽雙擊放大的圖片功能
flutter實現可縮放可拖拽雙擊放大的圖片功能 可縮放可拖拽的功能,可實現圖片或者其他widget的縮放已經拖拽並支援雙擊放大的功能 我們知道官方提供了雙擊縮放,但是不支援拖拽的功能,我們要實現向百度地圖那樣可以縮放又可以拖拽的功能,官方的方法就不支援了。下面先演示下功能: 引數只有兩個:1、child
使用Opencv實現圖片縮放
方法一: 實現步驟 1. load 載入圖片 2. info 讀取圖片資訊 3. resize 設定寬高
點選螢幕對顯示物件進行操作:調整位置/旋轉縮放模式/拖動
1.載入資源 2.將資源新增到顯示列表並設定錨點 ////////////////////////////////*調整位置關鍵程式碼*/ this.stage.addEventListener(egret.TouchEvent.TOUCH_BEGIN, (e: egret.TouchEvent) =&
php實現圖片縮放,超詳細註釋
<?php //header("content-type:image/png"); * @todo 把一張圖片按照使用者定義的高寬進行縮放,並把處理後的圖片重新命名,放在指定資料夾 * @param string $width:使用者定義的需要處理成的目標寬度 * @param string
js滑鼠滾輪事件詳解(全相容ie、chrome、firefox)實現圖片縮放
以前看到的都是用IE的zoom,所以非IE就不支援,昨天看到這個js中滑鼠滾輪事件詳解,於是完全相容(IE6-8,FF,Chrome,Opera,Safari)的滑鼠滾軸縮放圖片效果今天就誕生了 ====程式碼如下: var zooming=function(e){ e=window.event
研究中完美顯示K線圖:縮放、拖動、多圖MACD疊加
原文請看:https://www.joinquant.com/post/13121?tag=algorithm 2018年11月30日更新: 修正了MACD線不顯示的問題。 以下是原文: 想展現資料,圖無疑是最好的方式。展示股票資料,當然是K線圖了,之前論內有人用matplotlib
RecyclerView 實現側滑刪除和拖動排序
在使用ListView的時候實現拖動排序,主要靠繼承別人第三方的,在網上有很多例子, 這裡不介紹,主要是介紹一下recycleview的拖動排序和滑動刪除 一、主要知識點: 1、 ItemTouchHelper.Callback的使用
關於百度地圖縮放和拖拽的回撥函式
1.縮放的回撥函式 zoomstart {type, target} 地圖更改縮放級別開始時觸發觸發此事件 zoomend {type, target} 地圖更改縮放級別結束時觸發觸發此事件 a、實現縮放動作開始時,返回地圖中心點座標: map
OpenCV實現圖片縮放
import cv2 img = cv2.imread('./res/aero3.jpg') print(img.shape[:2]) height, width = img.shape[:2] reSize1 = cv2.resize(img, (2*
fresco如何配合PhotoView使用實現圖片縮放
這裡有兩種方法: 第一種:修改photoview https://github.com/ongakuer/PhotoDraweeView 第二種:繼承photoview,自定義DraweeView https://github.com/biezhihua/MySimpleD
IOS下,利用捏合手勢實現影象縮放和顯示
影象的縮放檢視,在移動終端上早已不是問題,任何一個人都能夠熟練的操作影象的縮放。本文所講述的重點並不是應用層面上的,而是從編碼的角度去自己實現一個影象的縮放應用。作者(就是我自己)最近在做一款APP,其中有一個功能就是抓取PC桌面的影象傳送到手機上顯示。雖說現在的手機螢幕
Glide 入門到精通之四——圖片縮放和調整大小
圖片調整大小和縮放是有趣的,在實際應用中也是很重要的 用 resize(x,y) 調整圖片大小 通常情況下,如果你的伺服器或者 API 提供的影象是你需要的精確尺寸,這時是完美的情況下,在記憶體小號和影象質量之間的權衡。 在和 Picasso 比較
C#圖片處理之:圖片縮放和剪裁
應聽眾點播要求,今天說說用C#做圖片的縮放和剪裁,相信很多人會對這部分內容感興趣,畢竟這個操作太實用了。 其實在GDI+中,縮放和剪裁可以看作同一個操作,無非就是原始區域的選擇不同罷了。空口無憑,先看具體演算法可能更好理解。 /// <summary&g
Android Bitmap圖片縮放優化,用canvas替代Matrix進行縮放,解決一些錯我
前面用Matrix來縮放Bitmap,發現有些情況下會丟擲錯誤,導致圖片空白。 /** * 縮放 * * @param bm * @param newWidth * @param newHeight *