记录每天学习到的内容-参考书第29章:Neil Smyth - Android Studio Electric Eel Essentials - Java Edition_ Developing Android Apps Using Android Studio 2022.1.1 and Java-Payload Media
如有错误欢迎指证
The GestureOverlayView Class
Android SDK 提供了GestureOverlayView 的class ,这是一个透明的view用于提供手势侦测。
侦测手势
注册一个GesturePerformedListener 事件监听器在GestureOverlayView class的实例上在外围的class implements OnGesturePerformedListener interface 以及对应的onGesturePerfomed callback函数如果一个手势监听器侦测到,onGesturePerformed callback function会被Android runtime system 启用。
建立自定义的手势
开发工具Gesture Builder Tool在模拟器google play下载,以建立自定义的手势,模拟器档案管理在View -> Tool Windows -> Device File Explorer手势档(gesture.txt)会在以下模拟器中的位置。/storage/emulated/0/Android/data/migueldp.runeforge/files/gestures.txt
将档案複製到专案中的res/raw里使用者介面
在activity中建立GestureOverlayView 的layer
此範例中id设为gOverlay
<android.gesture.GestureOverlayViewandroid:id="@+id/gOverlay"android:layout_width="0dp"android:layout_height="0dp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" />
读取手势档案
..import android.gesture.GestureOverlayView;import android.gesture.GestureOverlayView.OnGesturePerformedListener;import android.gesture.GestureLibraries;import android.gesture.GestureLibrary;public class MainActivity extends AppCompatActivity implements OnGesturePerformedListener { private ActivityMainBinding binding; private GestureLibrary gLibrary; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); gestureSetup(); } private void gestureSetup() { gLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures); if (!gLibrary.load()) { finish(); } }..}
除了之前讲到的 GestureOverlayView 以及OnGesturePerformedListener ,此程式建立了 GestureLibrary的实例gLibrary,用于载入位于res/raw里的手势档案,并且implement OnGesturePerformedListener interface,因此还会再往后补写onGesturePerformed callback function(因为是interface中的abstrack function)
注册OnGesturePerformedListener
为了让activity能收到使用者的手势,需要注册一个OnGesturePerformedListener到gLayout view 上,需增加以下程式码到gestureSetup()里面
GestureOverlayView gOverlay = findViewById(R.id.gOverlay);gOverlay.addOnGesturePerformedListener(this);
补写onGesturePerformed method
.import android.gesture.Prediction;import android.widget.Toast;import android.gesture.Gesture;import java.util.ArrayList;public class MainActivity extends AppCompatActivity implementsOnGesturePerformedListener {private GestureLibrary gLibrary;.. public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList<Prediction> predictions = gLibrary.recognize(gesture); if (predictions.size() > 0 && predictions.get(0).score > 1.0) { String action = predictions.get(0).name; Toast.makeText(this, action, Toast.LENGTH_SHORT).show(); } }...}
多增加上述函式库4个函式库,当手势再gOverlay view 上被侦测到onGesturePerformed method被呼叫,同时传入一个GestureOverlayView 的物件以及被侦测到的手势(type: Gesture),将侦测到的手势参数丢进gLibrary实例中的recognize(),目的是为了比较真测到的手势以及被从res/raw中读取到的手势档案,recognize()会回传一个ArrayList的物件包含一串Prediction物件,从最好排到最坏的预测,Prediction物件中包含了预测手势的名称以及预测分数。
在上述的程式码中判断手势是否评分大于1 ,如果满足条件,显示一个Toast message(显示弹跳通知)展示手势的名称
让手势变透明
在activity xml档中的android.gesture.GestureOverlayView增加最下面两行
<android.gesture.GestureOverlayViewandroid:id="@+id/gOverlay"android:layout_width="0dp"android:layout_height="0dp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"android:gestureColor="#00000000"android:uncertainGestureColor="#00000000" />
侦测pinch手势(zoom in/ zoom out)
implements SimpleOnScaleGestureListener interface 需要複写onScale(), onScaleBegin() and onScaleEnd() callback methods创造一个ScaleGestureDetector class的实例複写onTouchEvent() callback method 在最外围的activity
..import android.view.MotionEvent;import android.view.ScaleGestureDetector;import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;public class MainActivity extends AppCompatActivity { private ActivityMainBinding binding; ScaleGestureDetector scaleGestureDetector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); View view = binding.getRoot(); setContentView(view); scaleGestureDetector = new ScaleGestureDetector(this, new MyOnScaleGestureListener()); } @Override public boolean onTouchEvent(MotionEvent event) { scaleGestureDetector.onTouchEvent(event); return true; } public class MyOnScaleGestureListener extends SimpleOnScaleGestureListener { @Override public boolean onScale(ScaleGestureDetector detector) { float scaleFactor = detector.getScaleFactor(); if (scaleFactor > 1) { binding.myTextView.setText("Zooming Out"); } else { binding.myTextView.setText("Zooming In"); } return true; } @Override public boolean onScaleBegin(ScaleGestureDetector detector) { return true; } @Override public void onScaleEnd(ScaleGestureDetector detector) { } }...}
参考书:Neil Smyth - Android Studio Electric Eel Essentials - Java Edition_ Developing Android Apps Using Android Studio 2022.1.1 and Java-Payload Media