国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Android - Android實現手勢滑動多點觸摸縮放平移圖片效果

Android實現手勢滑動多點觸摸縮放平移圖片效果

2021-05-28 15:49鴻洋_ Android

這篇文章主要介紹了Android實現手勢滑動多點觸摸縮放平移圖片效果,實現圖片支持多點觸控,自由的進行縮放、平移的注意事項,感興趣的小伙伴們可以參考一下

現在app中,圖片預覽功能肯定是少不了的,用戶基本已經形成條件反射,看到小圖,點擊看大圖,看到大圖兩個手指開始進行放大,放大后,開始移動到指定部位。
一、概述
想要做到圖片支持多點觸控,自由的進行縮放、平移,需要了解幾個知識點:matrix , gesturedetector , scalegesturedetector 以及事件分發機制,ps:不會咋辦,不會你懂的。
1、matrix
矩陣,看深入了都是3維矩陣的乘啊什么的,怪麻煩的~~
其實這么了解下就行了:
matrix
數據結構3維矩陣;
內部存儲:new float[9] ; 內部就是個一維數組,內部9個元素;可以進行setvalues(float[] values)進行初始化
每個元素代表的意思:

?
1
2
3
4
5
{
    mscale_x, mskew_x, mtrans_x, 
        mskew_y, mscale_y, mtrans_y, 
        mpersp_0, mpersp_1, mpersp_2 
}; 

字面上,應該能看出來哪個代表x方向縮放,哪個代表垂直方向的偏移量吧~~有不認識的3個,沒事,請無視。
操作
比如你想要設置matrix的偏移量為200,100
你可以這么寫:

?
1
2
3
matrix transmatrix = new matrix();
    float[] values = new float[] { 1.0, 0, 200, 0, 1.0, 100, 0, 0, 1.0 };
    transmatrix.setvalues(values);

如果需要在旋轉30度,放大兩倍~~
這么寫其實怪麻煩的~~
matrix提供了一些常用的api:例如我們可以這么寫:

?
1
2
matrix transmatrix = new matrix();
    transmatrix.posttranslate(200, 100);

Android實現手勢滑動多點觸摸縮放平移圖片效果

如何獲取值:
當然了,我們對一個matrix進行了各種操作,一會postscale,一會posttranslate;那么現在如何獲得當前的縮放比例:
前面說setvalues可以初始化,那么getvalues就能拿到當前矩陣的值,拿到的是個一維數組,9個元素;再通過下標取對應值就可以。
比如我想知道現在x方向縮放比例:

?
1
2
3
4
5
public final float getscale()
  {
    scalematrix.getvalues(matrixvalues);
    return matrixvalues[matrix.mscale_x];
  }

好了,知道這些就夠了~~
2、gesturedetector
嗯,自己看api,能夠捕捉到長按、雙擊什么的;用法會在例子中
3、scalegesturedetector
嗯,有點像繼承來的,其實不是的,獨立的一個類~用于檢測縮放的手勢~~~用法會在例子中
二、實戰
為了大家更好的理解,我會獨立出每個功能,最后再整合到一起~~也方面大家對每個api的使用的學習。
1、自由的縮放
需求:當圖片加載時,將圖片在屏幕中居中;圖片寬或高大于屏幕的,縮小至屏幕大小;自由對圖片進行方法或縮小;
代碼不是很長,直接貼代碼了

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
package com.zhy.view;
 
import android.content.context;
import android.graphics.matrix;
import android.graphics.drawable.drawable;
import android.util.attributeset;
import android.util.log;
import android.view.motionevent;
import android.view.scalegesturedetector;
import android.view.scalegesturedetector.onscalegesturelistener;
import android.view.view;
import android.view.view.ontouchlistener;
import android.view.viewtreeobserver;
import android.widget.imageview;
 
public class zoomimageview extends imageview implements onscalegesturelistener,
    ontouchlistener, viewtreeobserver.ongloballayoutlistener
 
{
  private static final string tag = zoomimageview.class.getsimplename();
   
  public static final float scale_max = 4.0f;
  /**
   * 初始化時的縮放比例,如果圖片寬或高大于屏幕,此值將小于0
   */
  private float initscale = 1.0f;
 
  /**
   * 用于存放矩陣的9個值
   */
  private final float[] matrixvalues = new float[9];
 
  private boolean once = true;
 
  /**
   * 縮放的手勢檢測
   */
  private scalegesturedetector mscalegesturedetector = null;
 
  private final matrix mscalematrix = new matrix();
 
  public zoomimageview(context context)
  {
    this(context, null);
  }
 
  public zoomimageview(context context, attributeset attrs)
  {
    super(context, attrs);
    super.setscaletype(scaletype.matrix);
    mscalegesturedetector = new scalegesturedetector(context, this);
    this.setontouchlistener(this);
  }
 
  @override
  public boolean onscale(scalegesturedetector detector)
  {
    float scale = getscale();
    float scalefactor = detector.getscalefactor();
 
    if (getdrawable() == null)
      return true;
 
    /**
     * 縮放的范圍控制
     */
    if ((scale < scale_max && scalefactor > 1.0f)
        || (scale > initscale && scalefactor < 1.0f))
    {
      /**
       * 最大值最小值判斷
       */
      if (scalefactor * scale < initscale)
      {
        scalefactor = initscale / scale;
      }
      if (scalefactor * scale > scale_max)
      {
        scalefactor = scale_max / scale;
      }
      /**
       * 設置縮放比例
       */
      mscalematrix.postscale(scalefactor, scalefactor, getwidth() / 2,
          getheight() / 2);
      setimagematrix(mscalematrix);
    }
    return true;
 
  }
 
  @override
  public boolean onscalebegin(scalegesturedetector detector)
  {
    return true;
  }
 
  @override
  public void onscaleend(scalegesturedetector detector)
  {
  }
 
  @override
  public boolean ontouch(view v, motionevent event)
  {
    return mscalegesturedetector.ontouchevent(event);
 
  }
 
   
  /**
   * 獲得當前的縮放比例
   *
   * @return
   */
  public final float getscale()
  {
    mscalematrix.getvalues(matrixvalues);
    return matrixvalues[matrix.mscale_x];
  }
 
  @override
  protected void onattachedtowindow()
  {
    super.onattachedtowindow();
    getviewtreeobserver().addongloballayoutlistener(this);
  }
 
  @suppresswarnings("deprecation")
  @override
  protected void ondetachedfromwindow()
  {
    super.ondetachedfromwindow();
    getviewtreeobserver().removeglobalonlayoutlistener(this);
  }
 
  @override
  public void ongloballayout()
  {
    if (once)
    {
      drawable d = getdrawable();
      if (d == null)
        return;
      log.e(tag, d.getintrinsicwidth() + " , " + d.getintrinsicheight());
      int width = getwidth();
      int height = getheight();
      // 拿到圖片的寬和高
      int dw = d.getintrinsicwidth();
      int dh = d.getintrinsicheight();
      float scale = 1.0f;
      // 如果圖片的寬或者高大于屏幕,則縮放至屏幕的寬或者高
      if (dw > width && dh <= height)
      {
        scale = width * 1.0f / dw;
      }
      if (dh > height && dw <= width)
      {
        scale = height * 1.0f / dh;
      }
      // 如果寬和高都大于屏幕,則讓其按按比例適應屏幕大小
      if (dw > width && dh > height)
      {
        scale = math.min(dw * 1.0f / width, dh * 1.0f / height);
      }
      initscale = scale;
      // 圖片移動至屏幕中心
            mscalematrix.posttranslate((width - dw) / 2, (height - dh) / 2);
      mscalematrix
          .postscale(scale, scale, getwidth() / 2, getheight() / 2);
      setimagematrix(mscalematrix);
      once = false;
    }
 
  }
 
}

1)、我們在ongloballayout的回調中,根據圖片的寬和高以及屏幕的寬和高,對圖片進行縮放以及移動至屏幕的中心。如果圖片很小,那就正常顯示,不放大了~
2)、我們讓ontouchlistener的motionevent交給scalegesturedetector進行處理

?
1
2
3
4
5
6
@override
  public boolean ontouch(view v, motionevent event)
  {
    return mscalegesturedetector.ontouchevent(event);
 
  }

3)、在onscale的回調中對圖片進行縮放的控制,首先進行縮放范圍的判斷,然后設置mscalematrix的scale值
現在的效果:
1、小于屏幕的寬和高

Android實現手勢滑動多點觸摸縮放平移圖片效果

2、大于屏幕的寬和高

Android實現手勢滑動多點觸摸縮放平移圖片效果

可是,可是,存在問題:

  • 1、縮放的中心點,我們設置是固定的,屏幕中間
  • 2、放大后,無法移動

下面,我們先解決縮放的中心點問題,不能一直按屏幕中心么,像我這樣的,我比較關注妹子的眼睛,我要放大那一塊~~~
2、設置縮放中心
1、單純的設置縮放中心
僅僅是設置中心很簡單,直接修改下中心點 :

?
1
2
3
4
5
6
/**
       * 設置縮放比例
       */
      mscalematrix.postscale(scalefactor, scalefactor,
          detector.getfocusx(), detector.getfocusx());
      setimagematrix(mscalematrix);

但是,隨意的中心點放大、縮小,會導致圖片的位置的變化,最終導致,圖片寬高大于屏幕時,圖片與屏幕間出現白邊;圖片小于屏幕,但是不居中。
2、控制縮放時圖片顯示的范圍
所以我們在縮放的時候需要手動控制下范圍:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/**
   * 在縮放時,進行圖片顯示范圍的控制
   */
  private void checkborderandcenterwhenscale()
  {
 
    rectf rect = getmatrixrectf();
    float deltax = 0;
    float deltay = 0;
 
    int width = getwidth();
    int height = getheight();
 
    // 如果寬或高大于屏幕,則控制范圍
    if (rect.width() >= width)
    {
      if (rect.left > 0)
      {
        deltax = -rect.left;
      }
      if (rect.right < width)
      {
        deltax = width - rect.right;
      }
    }
    if (rect.height() >= height)
    {
      if (rect.top > 0)
      {
        deltay = -rect.top;
      }
      if (rect.bottom < height)
      {
        deltay = height - rect.bottom;
      }
    }
    // 如果寬或高小于屏幕,則讓其居中
    if (rect.width() < width)
    {
      deltax = width * 0.5f - rect.right + 0.5f * rect.width();
    }
    if (rect.height() < height)
    {
      deltay = height * 0.5f - rect.bottom + 0.5f * rect.height();
    }
    log.e(tag, "deltax = " + deltax + " , deltay = " + deltay);
 
    mscalematrix.posttranslate(deltax, deltay);
 
  }
 
  /**
   * 根據當前圖片的matrix獲得圖片的范圍
   *
   * @return
   */
  private rectf getmatrixrectf()
  {
    matrix matrix = mscalematrix;
    rectf rect = new rectf();
    drawable d = getdrawable();
    if (null != d)
    {
      rect.set(0, 0, d.getintrinsicwidth(), d.getintrinsicheight());
      matrix.maprect(rect);
    }
    return rect;
  }

在onscale里面記得調用:

?
1
2
3
4
5
6
7
/**
       * 設置縮放比例
       */
      mscalematrix.postscale(scalefactor, scalefactor,
          detector.getfocusx(), detector.getfocusy());
      checkborderandcenterwhenscale();
      setimagematrix(mscalematrix);

這樣就好了,可以自由的放大任何地方,并且不會出現邊界出現白邊,也能很好的讓圖片顯示在屏幕中間(當圖片寬或高小于屏幕);
3、貼下布局文件

?
1
2
3
4
5
6
7
8
9
10
11
12
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent" >
 
  <com.zhy.view.zoomimageview
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scaletype="matrix"
    android:src="@drawable/xx" />
 
</relativelayout>

眼睛是心靈的窗戶,咱們來放大看看,效果圖:

Android實現手勢滑動多點觸摸縮放平移圖片效果

好了,到此我們的圖片隨意的方法縮小~~~已經完成了~~~如果只需要縮放功能的,就可以拿去用了~
由于篇幅原因,下一篇將繼續完善此view:
1、增加多點觸控時移動
2、增加雙擊變大,雙擊變小
3、與viewpager一起使用時的事件沖突問題

以上就是本文的全部內容,希望對大家學習android軟件編程有所幫助。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 色视频www在线播放国产人成 | 国产黄大片 | 黄色一级大片在线免费看产 | 久久精品国产亚洲一区二区三区 | 精品视频一区二区三区四区 | 日韩一二区 | 欧美狠狠 | 欧美日韩一区二区三区不卡视频 | 国产精品久久久久久婷婷天堂 | 高清国产一区 | 欧美在线高清 | 午夜视频网站 | 毛片一级av | 国产成人影院 | 91粉色视频| 亚洲综合中文 | 国产高潮失禁喷水爽网站 | 亚洲成人精品在线 | 亚洲xxxx3d | 欧美成人精品一区二区男人看 | 天天干天天操天天干 | 国产区视频在线观看 | 久久精品播放 | 高清中文字幕 | 午夜久久久 | 在线无码 | 国产精品久久久久精 | 中文字幕在线观看视频地址二 | 久久久亚洲精品一区二区三区 | 国产日韩视频 | 国产成人免费在线 | 免费日韩 | 国产精品视频网 | 亚洲一二三 | 少妇一区二区三区免费观看 | 日本韩国欧美一区 | 亚洲视频在线观看 | 日韩有码一区二区三区 | 午夜免费福利影院 | 亚洲精品免费观看 | av久草|