Android_手势

Android关于手势的操作提供两种形式:一种是针对用户手指在屏幕上划出的动作而进行移动的检测,这些手势的检测通过android提供的监听器来实现;另一种是用户手指在屏幕上滑动而形成一定的不规则的几何图形(即为多个持续触摸事件在屏幕形成特定的形状);

  • frameworks/base/core/java/android/gesture todo? 需要理解这个具体库

1. 手势图片缩放

protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // 创建手势检测器
    detector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2,
                               float velocityX, float velocityY)  // ②
        {
            float vx = velocityX > 4000 ? 4000f : velocityX;
            vx = velocityX < -4000 ? -4000f : velocityX;
            // 根据手势的速度来计算缩放比,如果vx>0,则放大图片;否则缩小图片
            currentScale += currentScale * vx / 4000.0f;
            // 保证currentScale不会等于0
            currentScale = currentScale > 0.01 ? currentScale : 0.01f;
            // 重置Matrix
            matrix.reset();
            // 缩放Matrix
            matrix.setScale(currentScale, currentScale, 160f, 200f);
            BitmapDrawable tmp = (BitmapDrawable) imageView.getDrawable();
            // 如果图片还未回收,先强制回收该图片
            if (!tmp.getBitmap().isRecycled()) // ①
            {
                tmp.getBitmap().recycle();
            }
            // 根据原始位图和Matrix创建新图片
            Bitmap bitmap2 = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
            // 显示新的位图
            imageView.setImageBitmap(bitmap2);
            return true;
        }
    });
    imageView = findViewById(R.id.show);
    matrix = new Matrix();
    // 获取被缩放的源图片
    bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flower);
    // 获得位图宽
    width = bitmap.getWidth();
    // 获得位图高
    height = bitmap.getHeight();
    // 设置ImageView初始化时显示的图片
    imageView.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.flower));
}

2. 图片滑动

public class MainActivity extends Activity
{
	//  ViewFlipper实例
	private ViewFlipper flipper;
	// 定义手势检测器变量
	private GestureDetector detector;
	// 定义一个动画数组,用于为ViewFlipper指定切换动画效果
	private Animation[] animations = new Animation[4];
	// 定义手势动作两点之间的最小距离
	private float flipDistance = 0f;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		flipDistance = getResources().getDimension(R.dimen.flip_distance);
		// 创建手势检测器
		detector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener()
		{
			@Override public boolean onFling(MotionEvent event1, MotionEvent event2,
				float velocityX, float velocityY)
			{
				// 如果第一个触点事件的X坐标大于第二个触点事件的X坐标超过flipDistance
				// 也就是手势从右向左滑
				if (event1.getX() - event2.getX() > flipDistance)
				{
					// 为flipper设置切换的动画效果
					flipper.setInAnimation(animations[0]);
					flipper.setOutAnimation(animations[1]);
					flipper.showPrevious();
					return true;
				}
				// 如果第二个触点事件的X坐标大于第一个触点事件的X坐标超过flipDistance
				// 也就是手势从左向右滑
				else if (event2.getX() - event1.getX() > flipDistance)
				{
					// 为flipper设置切换的动画效果
					flipper.setInAnimation(animations[2]);
					flipper.setOutAnimation(animations[3]);
					flipper.showNext();
					return true;
				}
				return false;
			}
		});
		// 获得ViewFlipper实例
		flipper = this.findViewById(R.id.flipper);
		// 为ViewFlipper添加6个ImageView组件
		flipper.addView(addImageView(R.drawable.java));
		flipper.addView(addImageView(R.drawable.javaee));
		flipper.addView(addImageView(R.drawable.ajax));
		flipper.addView(addImageView(R.drawable.android));
		flipper.addView(addImageView(R.drawable.html));
		flipper.addView(addImageView(R.drawable.swift));
		// 初始化Animation数组
		animations[0] = AnimationUtils.loadAnimation(this, R.anim.left_in);
		animations[1] = AnimationUtils.loadAnimation(this, R.anim.left_out);
		animations[2] = AnimationUtils.loadAnimation(this, R.anim.right_in);
		animations[3] = AnimationUtils.loadAnimation(this, R.anim.right_out);
	}
	// 定义添加ImageView的工具方法
	private View addImageView(int resId)
	{
		ImageView imageView = new ImageView(this);
		imageView.setImageResource(resId);
		imageView.setScaleType(ImageView.ScaleType.CENTER);
		return imageView;
	}
	@Override public boolean onTouchEvent(MotionEvent event)
	{
		// 将该Activity上的触碰事件交给GestureDetector处理
		return detector.onTouchEvent(event);
	}
}

3. 添加手势

public class MainActivity extends Activity
{
	private GestureOverlayView gestureView;
	private Gesture gesture;
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		// 获取手势编辑视图
		gestureView = findViewById(R.id.gesture);
		// 设置手势的绘制颜色
		gestureView.setGestureColor(Color.RED);
		// 设置手势的绘制宽度
		gestureView.setGestureStrokeWidth(4f);
		// 为gesture的手势完成事件绑定事件监听器
		gestureView.addOnGesturePerformedListener((source, gesture) -> {
			this.gesture = gesture;
			// 请求访问写入SD卡的权限
			requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0x123);
		});
	}
	@Override
	public void onRequestPermissionsResult(int requestCode,
		String[] permissions, int[] grantResults)
	{
		// 如果确认允许访问
		if(requestCode == 0x123 && grantResults != null && grantResults[0] == 0)
		{
			// 加载dialog_save.xml界面布局代表的视图
			LinearLayout saveDialog = (LinearLayout) getLayoutInflater().inflate(R.layout.dialog_save, null);
			// 获取saveDialog里的show组件
			ImageView imageView = saveDialog.findViewById(R.id.show);
			// 获取saveDialog里的gesture_name组件
			EditText gestureName = saveDialog.findViewById(R.id.gesture_name);
			// 根据Gesture包含的手势创建一个位图
			Bitmap bitmap = gesture.toBitmap(128, 128, 10, -0x10000);
			imageView.setImageBitmap(bitmap);
			// 使用对话框显示saveDialog组件
			new AlertDialog.Builder(MainActivity.this).setView(saveDialog)
				.setPositiveButton(R.string.bn_save, (dialog, which) -> {
						// 获取指定文件对应的手势库
						GestureLibrary gestureLib = GestureLibraries.fromFile(
						Environment.getExternalStorageDirectory().getPath() + "/mygestures");
						// 添加手势
						gestureLib.addGesture(gestureName.getText().toString(), gesture);
						// 保存手势库
						gestureLib.save();
				}).setNegativeButton(R.string.bn_cancel, null).show();
		}
	}
}
0%