記錄每天學習到的內容-參考書第29章:Neil Smyth - Android Studio Electric Eel Essentials - Java Edition_ Developing Android Apps Using Android Studio 2022.1.1 and Java-Payload Media
如有錯誤歡迎指證
Android SDK 提供了GestureOverlayView 的class ,這是一個透明的view用於提供手勢偵測。
/storage/emulated/0/Android/data/migueldp.runeforge/files/gestures.txt
在activity中建立GestureOverlayView 的layer
此範例中id設為gOverlay
<android.gesture.GestureOverlayView
android: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)
為了讓activity能收到使用者的手勢,需要註冊一個OnGesturePerformedListener到gLayout view 上,需增加以下程式碼到gestureSetup()裡面
GestureOverlayView gOverlay = findViewById(R.id.gOverlay);
gOverlay.addOnGesturePerformedListener(this);
.
import android.gesture.Prediction;
import android.widget.Toast;
import android.gesture.Gesture;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity implements
OnGesturePerformedListener {
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.GestureOverlayView
android: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" />
..
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