Gesture手势
- 对于第一种手势行为而言,Android提供了手势检测,并为手势检测提供了相应的监听器;
- 对于第二种手势行为,Android允许开发者添加手势,并提供了相应的API识别用户手势。
publicclass MainActivity extends Activity {
privatefinalstatic String TAG = "MainActivity";
private GestureDetector detector;
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
detector = new GestureDetector(this, new OnGestureListener() {
@Override
publicboolean onSingleTapUp(MotionEvent e) {
Log.i(TAG, "==onSingleTapUp" + e.getAction());
returnfalse;
}
@Override
publicvoid onShowPress(MotionEvent e) {
Log.i(TAG, "==onShowPress" + e.getAction());
}
@Override
publicboolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
Log.i(TAG, "==onScroll" + e1.getAction() + ":" + e2.getAction());
returnfalse;
}
@Override
publicvoid onLongPress(MotionEvent e) {
Log.i(TAG, "==onLongPress" + e.getAction());
}
@Override
publicboolean onFling(MotionEvent e1, MotionEvent e2,
float velocityX, float velocityY) {
Log.i(TAG, "==onFling" + e1.getAction() + ":" + e2.getAction());
returnfalse;
}
@Override
publicboolean onDown(MotionEvent e) {
Log.i(TAG, "==onDown" + e.getAction());
returnfalse;
}
});
}
@Override
publicboolean onTouchEvent(MotionEvent event) {
returndetector.onTouchEvent(event);
}
}
publicclass MainActivity extends Activity {
private GestureDetector detector;
private ImageView imageView_main_show;
private Bitmap bitmap;// 初始的图片资源
privateintwidth, height;// 定义图片的宽、高
privatefloatcurrentScale = 1;// 记录当前的缩放比
private Matrix matrix;// 控制图片缩放的Matrix对象
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView_main_show = (ImageView) findViewById(R.id.imageView_main_show);
// 获取被缩放的源图片
matrix = new Matrix();
bitmap = BitmapFactory.decodeResource(this.getResources(),
R.drawable.lijiang);
width = bitmap.getWidth();// 获得位图宽
height = bitmap.getHeight();// 获得位图高
detector = new GestureDetector(this, new OnGestureListener() {
@Override
publicboolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
returnfalse;
}
@Override
publicvoid onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
}
@Override
publicboolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
// TODO Auto-generated method stub
returnfalse;
}
@Override
publicvoid onLongPress(MotionEvent e) {
// TODO Auto-generated method stub
}
@Override
publicboolean onFling(MotionEvent e1, MotionEvent e2,
float velocityX, float velocityY) {
velocityX = velocityX > 4000 ? 4000 : velocityX;
velocityX = velocityX < -4000 ? -4000 : velocityX;
// 根据手势的速度来计算缩放比,如果velocityX>0,放大图像,否则缩小图像。
currentScale += currentScale * velocityX / 4000.0f;
// 保证currentScale不会等于0
currentScale = currentScale > 0.01 ? currentScale : 0.01f;
// 重置Matrix
matrix.reset();
// 缩放Matrix
matrix.setScale(currentScale, currentScale, 0, 0);
// 如果图片还未回收,先强制回收该图片
BitmapDrawable bmDrawable = (BitmapDrawable) imageView_main_show
.getDrawable();
if (!bmDrawable.getBitmap().isRecycled()) {
bmDrawable.getBitmap().recycle();
}
// 根据原始位图和Matrix创建新图片
Bitmap bitmap_new = Bitmap.createBitmap(bitmap, 0, 0, width,
height, matrix, true);
// 显示新的位图
imageView_main_show.setImageBitmap(bitmap_new);
returnfalse;
}
@Override
publicboolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
returnfalse;
}
});
}
@Override
publicboolean onTouchEvent(MotionEvent event) {
returndetector.onTouchEvent(event);
}
}
publicclass MainActivity extends Activity {
privatestaticfinal String TAG = "MainActivity";
private ViewFlipper viewFlipper_main;
private GestureDetector detector;
private Animation leftInAnimation;
private Animation leftOutAnimation;
private Animation rightInAnimation;
private Animation rightOutAnimation;
privatefinalintFLIP_DISTANCE = 50;
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewFlipper_main = (ViewFlipper) findViewById(R.id.viewFlipper_main);
viewFlipper_main.addView(getImageView(R.drawable.img001));
viewFlipper_main.addView(getImageView(R.drawable.img012));
viewFlipper_main.addView(getImageView(R.drawable.img017));
viewFlipper_main.addView(getImageView(R.drawable.img021));
viewFlipper_main.addView(getImageView(R.drawable.img030));
viewFlipper_main.addView(getImageView(R.drawable.img031));
leftInAnimation = AnimationUtils.loadAnimation(this, R.anim.left_in);
leftOutAnimation = AnimationUtils.loadAnimation(this, R.anim.left_out);
rightInAnimation = AnimationUtils.loadAnimation(this, R.anim.right_in);
rightOutAnimation = AnimationUtils
.loadAnimation(this, R.anim.right_out);
detector = new GestureDetector(this, new OnGestureListener() {
@Override
publicboolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
returnfalse;
}
@Override
publicvoid onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
}
@Override
publicboolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
// TODO Auto-generated method stub
returnfalse;
}
@Override
publicvoid onLongPress(MotionEvent e) {
// TODO Auto-generated method stub
}
@Override
publicboolean onFling(MotionEvent event1, MotionEvent event2,
float velocityX, float velocityY) {
/*
* 如果第一个触点事件的X座标大于第二个触点事件的X座标超过FLIP_DISTANCE 也就是手势从右向左滑。
*/
if (event1.getX() - event2.getX() > FLIP_DISTANCE) {
Log.i(TAG, "==向左:e1-e2=" + (event1.getX() - event2.getX()));
// 为flipper设置切换的的动画效果
viewFlipper_main.setInAnimation(leftInAnimation);
viewFlipper_main.setOutAnimation(leftOutAnimation);
viewFlipper_main.showPrevious();
returntrue;
}
/*
* 如果第二个触点事件的X座标大于第一个触点事件的X座标超过FLIP_DISTANCE 也就是手势从左向右滑。
*/
elseif (event2.getX() - event1.getX() > FLIP_DISTANCE) {
Log.i(TAG, "==向右:e2-e1=" + (event2.getX() - event1.getX()));
// 为flipper设置切换的的动画效果
viewFlipper_main.setInAnimation(rightInAnimation);
viewFlipper_main.setOutAnimation(rightOutAnimation);
viewFlipper_main.showNext();
returntrue;
}
returnfalse;
}
@Override
publicboolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
returnfalse;
}
});
}
private ImageView getImageView(int id) {
ImageView imageView = new ImageView(this);
imageView.setImageResource(id);
return imageView;
}
@Override
publicboolean onTouchEvent(MotionEvent event) {
returndetector.onTouchEvent(event);
}
}
publicclass MyImageView extends ImageView {
privatefloatscale = 0.05f;
// 两点触屏后之间的长度
privatefloatbeforeLenght;
privatefloatafterLenght;
// 单点移动的前后坐标值
privatefloatafterX, afterY;
privatefloatbeforeX, beforeY;
public MyImageView(Context context) {
super(context);
}
public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protectedvoid onDraw(Canvas canvas) {
super.onDraw(canvas);
}
// 用来设置ImageView的位置
privatevoid setLocation(int x, int y) {
this.setFrame(this.getLeft() + x, this.getTop() + y, this.getRight()
+ x, this.getBottom() + y);
}
// 用来放大缩小ImageView. flag为0是放大图片,为1是缩小图片
privatevoid setScale(float scaleSize, int flag) {
if (flag == 0) {
this.setFrame(this.getLeft() - (int) (scaleSize * this.getWidth()),
this.getTop() - (int) (scaleSize * this.getHeight()),
this.getRight() + (int) (scaleSize * this.getWidth()),
this.getBottom() + (int) (scaleSize * this.getHeight()));
} else {
this.setFrame(this.getLeft() + (int) (scaleSize * this.getWidth()),
this.getTop() + (int) (scaleSize * this.getHeight()),
this.getRight() - (int) (scaleSize * this.getWidth()),
this.getBottom() - (int) (scaleSize * this.getHeight()));
}
}
/*
* 让图片跟随手指触屏的位置移动 beforeX、Y是用来保存前一位置的坐标 afterX、Y是用来保存当前位置的坐标
* 它们的差值就是ImageView各坐标的增加或减少值
*/
publicvoid moveWithFinger(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
beforeX = event.getX();
beforeY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
afterX = event.getX();
afterY = event.getY();
this.setLocation((int) (afterX - beforeX), (int) (afterY - beforeY));
beforeX = afterX;
beforeY = afterY;
break;
case MotionEvent.ACTION_UP:
break;
}
}
// 通过多点触屏放大或缩小图像 beforeLenght用来保存前一时间两点之间的距离 afterLenght用来保存当前时间两点之间的距离
publicvoid scaleWithFinger(MotionEvent event) {
float moveX = event.getX(1) - event.getX(0);
float moveY = event.getY(1) - event.getY(0);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
beforeLenght = (float) Math.sqrt((moveX * moveX) + (moveY * moveY));
break;
case MotionEvent.ACTION_MOVE:
// 得到两个点之间的长度
afterLenght = (float) Math.sqrt((moveX * moveX) + (moveY * moveY));
float gapLenght = afterLenght - beforeLenght;
// 如果当前时间两点距离大于前一时间两点距离,则传0,否则传1
if (gapLenght > 0) {
this.setScale(scale, 0);
} elseif (gapLenght < 0) {
this.setScale(scale, 1);
} elseif (gapLenght == 0) {
break;
}
beforeLenght = afterLenght;
break;
}
}
}
//利用多点触控来控制ImageView中图像的放大与缩小。如果是单点,则用手指控制图片移动
publicclass MainActivity extends Activity {
private MyImageView imageView;
private Bitmap bitmap;
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (MyImageView) findViewById(R.id.imageView_main_show);
bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
imageView.setImageBitmap(bitmap);
}
// 这里来监听屏幕触控事件
@Override
publicboolean onTouchEvent(MotionEvent event) {
if (event.getPointerCount() == 2) {
imageView.scaleWithFinger(event);
} elseif (event.getPointerCount() == 1) {
imageView.moveWithFinger(event);
}
returntrue;
}
}
- static GestureLibrary fromFile(String path)
- static GestureLibrary fromFile(File path)
- static GestureLibrary fromPrivateFile(Context context , String name)
- static GestureLibrary fromRawResource(Context context , int resourceId)
- void addGesture(String entryName , Gesture gesture)
- 添加一个名为entryName的手势。
- Set<String> getGestureEntries()
- 获取该手势库中的所有手势的名称。
- ArrayList<Gesture> getGestures (String entryName)
- 获取entryName所对应的所有手势。
- ArrayList<Prediction> recognize (Gesture gesture)
- 从当前手势库中识别与gesture匹配的全部手势。
- void removeEntry (String entryName)
- 删除手势库中entryName对应的手势。
- void removeGesture (String entryName , Gesture gesture)
- 删除手势库中entryName、gesture 对应的手势。
- boolean save()
- 当向手势库中添加手势或从中删除手势后调用该方法以此来保存手势库。
publicclass MainActivity extends Activity {
private GestureOverlayView gestureOverlayView_main;
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gestureOverlayView_main = (GestureOverlayView) findViewById(R.id.gestureOverlayView_main);
gestureOverlayView_main
.addOnGesturePerformedListener(new OnGesturePerformedListener() {
@Override
publicvoid onGesturePerformed(GestureOverlayView overlay,
final Gesture gesture) {
View dialog_savegesture = getLayoutInflater().inflate(
R.layout.dialog_savegesture, null);
final EditText editText_dialog_gesturename = (EditText) dialog_savegesture
.findViewById(R.id.editText_dialog_gesturename);
ImageView imageView_dialog_showgesture = (ImageView) dialog_savegesture
.findViewById(R.id.imageView_dialog_showgesture);
Bitmap bm = gesture.toBitmap(120, 120, 0, Color.CYAN);
imageView_dialog_showgesture.setImageBitmap(bm);
AlertDialog.Builder builder = new AlertDialog.Builder(
MainActivity.this);
builder.setView(dialog_savegesture);
builder.setPositiveButton("保存", new OnClickListener() {
@Override
publicvoid onClick(DialogInterface dialog,
int which) {
GestureLibrary gestureLibrary = GestureLibraries
.fromFile("/mnt/sdcard/mygestures");
gestureLibrary.addGesture(
editText_dialog_gesturename.getText()
.toString(), gesture);
gestureLibrary.save();
}
});
builder.setNegativeButton("取消", null);
builder.show();
}
});
}
}
- Prediction对象的name属性:手势名;
- Prediction对象的score属性:手势相似度。
publicclass MainActivity extends Activity {
private GestureOverlayView gestureOverlayView_main;
private GestureLibrary gestureLibrary;
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gestureLibrary = GestureLibraries.fromFile("/mnt/sdcard/mygestures");
if (gestureLibrary.load()) {
Toast.makeText(this, "手势加载ok!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "手势加载失败!", Toast.LENGTH_SHORT).show();
}
gestureOverlayView_main = (GestureOverlayView) findViewById(R.id.gestureOverlayView_main);
gestureOverlayView_main
.addOnGesturePerformedListener(new OnGesturePerformedListener() {
@Override
publicvoid onGesturePerformed(GestureOverlayView overlay,
Gesture gesture) {
ArrayList<Prediction> predictions = gestureLibrary
.recognize(gesture);
List<String> result = new ArrayList<String>();
for (Prediction prediction : predictions) {
if (prediction.score > 2) {
result.add("与手势" + prediction.name + "匹配相似度为:"
+ prediction.score);
}
}
if (result.size() > 0) {
Toast.makeText(MainActivity.this,
result.toString(), Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(MainActivity.this, "无匹配手势!",
Toast.LENGTH_SHORT).show();
}
}
});
}
}
良心的公众号,更多精品文章,不要忘记关注哈
《Android和Java技术栈》