這次做一個會用到手勢的應用,在 App 中放入一個 ImageView 通過手勢來拖動和縮放。
- 畫面中間放一個 ImageView
- ImageView 可以拖動、縮放
Custom ImageView
我通過在 MainActivity 同一個資料夾下建立一個 MovableImageView,然後在 activity_main.xml 中引用他。
1 |
<devdon.com.scalableimageview.MovableImageView /> |
和直接在 xml 的 Design 介面放入 component 的方式一樣,在 xml 中可以對其設定 layout,比如:
1 2 3 4 5 6 7 8 9 10 11 12 |
<devdon.com.scalableimageview.MovableImageView android:layout_width="300dp" android:layout_height="200dp" android:layout_marginBottom="8dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:src="@drawable/img_mountain_s" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> |
其中通過 android:src=”圖片路徑” 設定了 ImageView 的圖片。
ImageView 本身有提供幾個 init 的方法:
- ImageView(Context context)
- ImageView(Context context, AttributeSet attrs)
- ImageView(Context context, AttributeSet attrs, int defStyleAttr)
- ImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
這次的邏輯應該是類似 iOS 中的 Storyboard 來初始化介面,所以通過定義好的 layout 用下面的方法來初始化:
1 |
public constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {} |
座標體系
和 iOS 一樣的地方,左上角為 (0,0),最右下角為 (max, max)
除了 ViewController 有自己的座標系以外,所有的 View 都會有一個自身的座標系,也就是會有子 View 在 父 View 座標系中的相對位置之類的概念。
手勢
通過 onTouchEvent 來獲取手勢事件,不只是 Activity 可以 override , View 也有這個方法可以 override。
1 |
override fun onTouchEvent(event: MotionEvent?): Boolean {} |
MotionEvent 下,有定義幾個手勢類型,其中需要注意的是 action_pointer_down 這樣的方法,是多指操作的定義,比如:
- ACTION_DOWN – 單指按下
- ACTION_POINTER_DOWN – 多指按下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
override fun onTouchEvent(event: MotionEvent?): Boolean { when(event?.actionMasked) { MotionEvent.ACTION_DOWN - > { println("action down") } MotionEvent.ACTION_POINTER_DOWN - > { println("pointer down") } MotionEvent.ACTION_MOVE - > { println("action move") } MotionEvent.ACTION_POINTER_UP - > { println("pointer up") } MotionEvent.ACTION_UP - > { println("action up") } } return super.onTouchEvent(event) } |
ImageView 操作
在拖動或者縮放的時候,通過 setFrame 來改變 ImageView 的座標和大小。
- setFrame(int left, int top, int right, int bottom) – Assign a size and position to this view.
思考
- ImageView 中圖片大小的問題,一開始我隨手下載來一張 5341 x 3561 大小的圖片,在 Design 中可以正常顯示,但是啟動 App 的時候就會直接 crash,後來手動把圖片縮小到 512 x 342 就沒問題了,所以可能有限制圖片大小,又或者有記憶體問題。
參考
- 官方文件 – ImageView
- Loading Large Bitmaps Efficiency
- 可以到 Gtihub 上看對應的 Source Code