天天看點

【移動開發】Android中圖檔的多點觸控和縮放

   前幾天做項目用到相機拍照,之後能對圖檔進行縮放,拖拽,在此我将其單獨抽取出來,後面用到時直接拿來用就行了!

效果圖:

<a target="_blank" href="http://blog.51cto.com/attachment/201307/174133817.png"></a>

  注:這裡不僅能按鈕縮放,還能多點觸摸縮放和拖拽功能!

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

<code>&lt;?</code><code>xml</code> <code>version</code><code>=</code><code>"1.0"</code> <code>encoding</code><code>=</code><code>"UTF-8"</code><code>?&gt;</code>

<code>&lt;</code><code>FrameLayout</code> <code>xmlns:android</code><code>=</code><code>"http://schemas.android.com/apk/res/android"</code>

<code>    </code><code>android:id</code><code>=</code><code>"@+id/flayout_img_display"</code>

<code>    </code><code>android:layout_width</code><code>=</code><code>"fill_parent"</code>

<code>    </code><code>android:layout_height</code><code>=</code><code>"fill_parent"</code>

<code>    </code><code>android:orientation</code><code>=</code><code>"vertical"</code> <code>&gt;</code>

<code>    </code><code>&lt;</code><code>LinearLayout</code>

<code>        </code><code>android:id</code><code>=</code><code>"@+id/linearLayout_img_display"</code>

<code>        </code><code>android:layout_width</code><code>=</code><code>"fill_parent"</code>

<code>        </code><code>android:layout_height</code><code>=</code><code>"fill_parent"</code>

<code>        </code><code>android:layout_gravity</code><code>=</code><code>"center"</code>

<code>        </code><code>android:gravity</code><code>=</code><code>"center"</code> <code>&gt;</code>

<code>        </code><code>&lt;</code><code>ImageView</code>

<code>            </code><code>android:id</code><code>=</code><code>"@+id/img_display"</code>

<code>            </code><code>android:layout_width</code><code>=</code><code>"fill_parent"</code>

<code>            </code><code>android:layout_height</code><code>=</code><code>"wrap_content"</code>

<code>            </code><code>android:paddingBottom</code><code>=</code><code>"5.0dip"</code>

<code>            </code><code>android:paddingTop</code><code>=</code><code>"5.0dip"</code>

<code>            </code><code>android:scaleType</code><code>=</code><code>"matrix"</code> <code>/&gt;</code>

<code>    </code><code>&lt;/</code><code>LinearLayout</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>RelativeLayout</code>

<code>        </code><code>android:id</code><code>=</code><code>"@+id/relativeLayout1"</code>

<code>        </code><code>android:layout_height</code><code>=</code><code>"wrap_content"</code> <code>&gt;</code>

<code>        </code><code>&lt;</code><code>Button</code>

<code>            </code><code>android:id</code><code>=</code><code>"@+id/btn_min"</code>

<code>            </code><code>android:layout_width</code><code>=</code><code>"wrap_content"</code>

<code>            </code><code>android:layout_alignParentBottom</code><code>=</code><code>"true"</code>

<code>            </code><code>android:layout_alignParentLeft</code><code>=</code><code>"true"</code>

<code>            </code><code>android:enabled</code><code>=</code><code>"false"</code>

<code>            </code><code>android:text</code><code>=</code><code>"縮小"</code> <code>/&gt;</code>

<code>            </code><code>android:id</code><code>=</code><code>"@+id/btn_out"</code>

<code>            </code><code>android:layout_alignParentRight</code><code>=</code><code>"true"</code>

<code>            </code><code>android:text</code><code>=</code><code>"放大"</code> <code>/&gt;</code>

<code>    </code><code>&lt;/</code><code>RelativeLayout</code><code>&gt;</code>

<code>&lt;/</code><code>FrameLayout</code><code>&gt;</code>

2.就一個類:

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

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

<code>import</code> <code>android.app.Activity;</code>

<code>import</code> <code>android.content.Intent;</code>

<code>import</code> <code>android.graphics.Bitmap;</code>

<code>import</code> <code>android.graphics.BitmapFactory;</code>

<code>import</code> <code>android.graphics.Matrix;</code>

<code>import</code> <code>android.graphics.PointF;</code>

<code>import</code> <code>android.os.Bundle;</code>

<code>import</code> <code>android.util.FloatMath;</code>

<code>import</code> <code>android.util.Log;</code>

<code>import</code> <code>android.view.MotionEvent;</code>

<code>import</code> <code>android.view.View;</code>

<code>import</code> <code>android.view.View.OnClickListener;</code>

<code>import</code> <code>android.view.View.OnTouchListener;</code>

<code>import</code> <code>android.widget.Button;</code>

<code>import</code> <code>android.widget.FrameLayout;</code>

<code>import</code> <code>android.widget.ImageView;</code>

<code>import</code> <code>android.widget.LinearLayout;</code>

<code>/**</code>

<code> </code><code>* 縮放圖檔界面</code>

<code> </code><code>* @author ZHF</code>

<code> </code><code>*</code>

<code> </code><code>*/</code>

<code>public</code> <code>class</code> <code>MainActivity </code><code>extends</code> <code>Activity {</code>

<code>    </code><code>public</code> <code>static</code> <code>final</code> <code>String TAG = </code><code>"ImgDisplayActivity"</code><code>;</code>

<code>    </code><code>//控件聲明</code>

<code>    </code><code>private</code> <code>Button btnZoomin, btnZoomout;</code>

<code>    </code><code>private</code> <code>ImageView imgDisPlay;</code>

<code>    </code><code>private</code> <code>LinearLayout lLayoutDisplay;</code>

<code>    </code><code>private</code> <code>FrameLayout fLayoutDisplay;</code>

<code>                                                                                                           </code> 

<code>    </code><code>private</code> <code>Bitmap bitmap;</code>

<code>    </code><code>private</code> <code>int</code> <code>imgId = </code><code>0</code><code>;</code>

<code>    </code><code>private</code> <code>double</code> <code>scale_in = </code><code>0.8</code><code>;</code><code>//縮小比例</code>

<code>    </code><code>private</code> <code>double</code> <code>scale_out = </code><code>1.25</code><code>;</code><code>//放大比例</code>

<code>    </code><code>private</code> <code>float</code> <code>scaleWidth = </code><code>1</code><code>;</code>

<code>    </code><code>private</code> <code>float</code> <code>scaleHeight = </code><code>1</code><code>;</code>

<code>    </code><code>//模式:0:什麼都不幹;1:拖拽; 2:縮放</code>

<code>    </code><code>public</code> <code>static</code> <code>final</code> <code>int</code> <code>NONE = </code><code>0</code><code>;</code>

<code>    </code><code>public</code> <code>static</code> <code>final</code> <code>int</code> <code>DRAG = </code><code>1</code><code>;</code>

<code>    </code><code>public</code> <code>static</code> <code>final</code> <code>int</code> <code>ZOOM = </code><code>2</code><code>;</code>

<code>    </code><code>//聲明觸發的事件模式</code>

<code>    </code><code>private</code> <code>int</code> <code>mode = NONE;</code>

<code>    </code><code>private</code> <code>Matrix matrix;   </code><code>//矩陣</code>

<code>    </code><code>private</code> <code>Matrix currMatrix; </code><code>//目前矩陣</code>

<code>    </code><code>private</code> <code>PointF starPoint;</code>

<code>    </code><code>private</code> <code>PointF midPoint;</code>

<code>    </code><code>private</code> <code>float</code> <code>startDistance;</code>

<code>    </code><code>@Override</code>

<code>    </code><code>protected</code> <code>void</code> <code>onCreate(Bundle savedInstanceState) {</code>

<code>        </code><code>super</code><code>.onCreate(savedInstanceState);</code>

<code>        </code><code>setContentView(R.layout.activity_main);</code>

<code>        </code><code>//初始化</code>

<code>        </code><code>fLayoutDisplay = (FrameLayout) findViewById(R.id.flayout_img_display);</code>

<code>        </code><code>lLayoutDisplay = (LinearLayout) findViewById(R.id.linearLayout_img_display);</code>

<code>        </code><code>imgDisPlay = (ImageView) findViewById(R.id.img_display);</code>

<code>        </code><code>btnZoomin = (Button) findViewById(R.id.btn_min);</code>

<code>        </code><code>btnZoomout = (Button) findViewById(R.id.btn_out);</code>

<code>                                                                                                               </code> 

<code>        </code><code>matrix = </code><code>new</code> <code>Matrix(); </code><code>//儲存拖拽變化</code>

<code>        </code><code>currMatrix = </code><code>new</code> <code>Matrix();</code><code>// 目前的</code>

<code>        </code><code>starPoint = </code><code>new</code> <code>PointF();</code><code>//開始點的位置</code>

<code>        </code><code>btnZoomin.setOnClickListener(</code><code>new</code> <code>OnClickListener() {</code>

<code>            </code><code>@Override</code>

<code>            </code><code>public</code> <code>void</code> <code>onClick(View v) {</code>

<code>                </code><code>zoomIn();</code>

<code>            </code><code>}</code>

<code>        </code><code>});</code>

<code>        </code><code>btnZoomout.setOnClickListener(</code><code>new</code> <code>OnClickListener() {</code>

<code>                </code><code>zoomOut();</code><code>//放大</code>

<code>        </code><code>imgDisPlay.setImageResource(R.drawable.img);</code>

<code>        </code><code>//給圖檔綁定監聽器哦</code>

<code>        </code><code>imgDisPlay.setOnTouchListener(</code><code>new</code> <code>ImageViewOnTouchListener());</code>

<code>    </code><code>}</code>

<code>    </code><code>/**放大操作**/</code>

<code>    </code><code>private</code> <code>void</code> <code>zoomOut() {</code>

<code>        </code><code>reSizeBmp(scale_out);</code>

<code>        </code><code>btnZoomin.setEnabled(</code><code>true</code><code>);</code>

<code>    </code><code>/**縮小操作**/</code>

<code>    </code><code>private</code> <code>void</code> <code>zoomIn() {</code>

<code>        </code><code>reSizeBmp(scale_in);</code>

<code>    </code><code>/**接收傳入的縮放比例實作縮放**/</code>

<code>    </code><code>private</code> <code>void</code> <code>reSizeBmp(</code><code>double</code> <code>scale) {</code>

<code>        </code><code>//縮放比例</code>

<code>        </code><code>scaleWidth = (</code><code>float</code><code>) (scaleWidth * scale);</code>

<code>        </code><code>scaleHeight = (</code><code>float</code><code>) (scaleHeight * scale);</code>

<code>        </code><code>Matrix matrix = </code><code>new</code> <code>Matrix();</code>

<code>        </code><code>matrix.postScale(scaleWidth, scaleHeight); </code><code>//設計縮放比例</code>

<code>        </code><code>imgDisPlay.setImageMatrix(matrix);</code>

<code>    </code><code>/**計算觸摸實作縮放**/</code>

<code>    </code><code>final</code> <code>class</code> <code>ImageViewOnTouchListener </code><code>implements</code> <code>OnTouchListener{</code>

<code>        </code><code>@Override</code>

<code>        </code><code>public</code> <code>boolean</code> <code>onTouch(View v, MotionEvent event) {</code>

<code>                                                                                                                   </code> 

<code>            </code><code>switch</code> <code>(event.getAction() &amp; MotionEvent.ACTION_MASK) {</code>

<code>            </code><code>case</code> <code>MotionEvent.ACTION_DOWN:  </code><code>//一隻手指按下</code>

<code>                </code><code>Log.i(TAG,</code><code>"一隻手指按下"</code><code>);</code>

<code>                </code><code>currMatrix.set(matrix);</code>

<code>                </code><code>starPoint.set(event.getX(), event.getY());</code>

<code>                                                                                                                       </code> 

<code>                </code><code>mode = DRAG;</code>

<code>                </code><code>break</code><code>;</code>

<code>            </code><code>case</code> <code>MotionEvent.ACTION_POINTER_DOWN: </code><code>//如果有一隻手指按下螢幕,後續又有一個手指按下     // 兩隻手指按下</code>

<code>                </code><code>Log.i(TAG,</code><code>"又有一隻手指按下"</code><code>);</code>

<code>                </code><code>startDistance = distance(event);</code><code>//記下兩點的距離</code>

<code>                </code><code>Log.i(TAG, startDistance+</code><code>""</code><code>);</code>

<code>                </code><code>if</code><code>(startDistance &gt; 5f) {  </code><code>//兩個手指之間的最小距離像素大于5,認為是多點觸摸</code>

<code>                    </code><code>mode = ZOOM;</code>

<code>                    </code><code>currMatrix.set(matrix);</code>

<code>                                                                                                                           </code> 

<code>                    </code><code>midPoint = getMidPoint(event); </code><code>//記下兩個點之間的中心點</code>

<code>                </code><code>}</code>

<code>            </code><code>case</code> <code>MotionEvent.ACTION_MOVE:</code>

<code>                </code><code>if</code><code>(mode == DRAG) {  </code><code>//拖拽模式</code>

<code>                    </code><code>Log.i(TAG,</code><code>"一隻手指在拖拽"</code><code>);</code>

<code>                    </code><code>//開始--》結束點的距離</code>

<code>                    </code><code>float</code> <code>dx = event.getX() - starPoint.x;</code>

<code>                    </code><code>float</code> <code>dy = event.getY() - starPoint.y;</code>

<code>                    </code><code>matrix.set(currMatrix);</code>

<code>                    </code><code>matrix.postTranslate(dx, dy);</code><code>//移動到指定點:矩陣移動比例;eg:縮放有縮放比例</code>

<code>                </code><code>} </code><code>else</code> <code>if</code><code>(mode == ZOOM) {  </code><code>//縮放模式</code>

<code>                    </code><code>Log.i(TAG,</code><code>"正在縮放"</code><code>);</code>

<code>                    </code><code>float</code> <code>distance = distance(event);  </code><code>//兩點之間的距離</code>

<code>                    </code><code>if</code><code>(distance &gt; 5f) {</code>

<code>                        </code><code>matrix.set(currMatrix);</code>

<code>                        </code><code>float</code> <code>cale = distance / startDistance;</code>

<code>                        </code><code>matrix.preScale(cale, cale, midPoint.x, midPoint.y);  </code><code>//進行比例縮放</code>

<code>                    </code><code>}</code>

<code>            </code><code>case</code> <code>MotionEvent.ACTION_UP: </code><code>//最後一隻手指離開螢幕後觸發此事件</code>

<code>            </code><code>case</code> <code>MotionEvent.ACTION_POINTER_UP: </code><code>//一隻手指離開螢幕,但還有一隻手指在上面會觸此事件</code>

<code>                </code><code>//什麼都沒做</code>

<code>                </code><code>mode = NONE;</code>

<code>            </code><code>default</code><code>:</code>

<code>            </code><code>imgDisPlay.setImageMatrix(matrix);</code>

<code>            </code><code>//兩隻手指的縮放</code>

<code>            </code><code>return</code> <code>true</code><code>;</code>

<code>        </code><code>}</code>

<code>    </code><code>/**計算兩點之間的距離像素**/</code>

<code>    </code><code>private</code> <code>float</code> <code>distance(MotionEvent e) {</code>

<code>        </code><code>float</code> <code>eX = e.getX(</code><code>1</code><code>) - e.getX(</code><code>0</code><code>);  </code><code>//後面的點坐标 - 前面點的坐标</code>

<code>        </code><code>float</code> <code>eY = e.getY(</code><code>1</code><code>) - e.getY(</code><code>0</code><code>);</code>

<code>        </code><code>return</code> <code>FloatMath.sqrt(eX * eX + eY * eY);</code>

<code>    </code><code>/**計算兩點之間的中心點**/</code>

<code>    </code><code>private</code> <code>PointF getMidPoint(MotionEvent event) {</code>

<code>        </code><code>float</code> <code>x = (event.getX(</code><code>1</code><code>) - event.getX(</code><code>0</code><code>)) / </code><code>2</code><code>;</code>

<code>        </code><code>float</code> <code>y = (event.getY(</code><code>1</code><code>) - event.getY(</code><code>0</code><code>)) / </code><code>2</code><code>;</code>

<code>        </code><code>return</code> <code>new</code> <code>PointF(x,y);</code>

<code>}</code>

    ok!主要的算法就在ImageViewOnTouchListener監聽器當中,要考慮那三種情況(縮放、拖拽、什麼都不幹),另外需要注意的就是,單個手指和兩個以上手指的情況。

     本文轉自zhf651555765 51CTO部落格,原文連結:http://blog.51cto.com/smallwoniu/1252191,如需轉載請自行聯系原作者