Android应用开发之图片拖拉和多点触摸缩放
来源:互联网 发布:法国黑白混血 知乎 编辑:程序博客网 时间:2024/05/16 11:01
传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229
今天我们学习如何实现图片(理论上选取的图片实际尺寸应大于当前手机的屏幕尺寸)拖拉和多点触摸缩放功能。其中多点触摸缩放功能模拟器上不支持,需要在真机下测试。下面给出该场景的案例:
1案例技术要点
(1)图片变换矩阵(android.graphics.Matrix):提供记录图片位置、记录图片缩放比例、实现图片移动等。
(2)图片坐标点(android.graphics.PointF):提供记录图片起点和中心点坐标等。
(3)重写图片所在Activity的onTouch(...)方法,处理以下几个事件:
MotionEvent.ACTION_DOWN:触点(手指)按下时触发该事件
MotionEvent.ACTION_POINTER_DOWN:当屏幕上已经有触点(手指),再有触点(手指)按下时触发该事件
MotionEvent.ACTION_MOVE:触点(手指)移动时触发该事件
MotionEvent.ACTION_UP:触点(手指)离开屏幕时触发该事件
MotionEvent.ACTION_POINTER_UP:当触点(手指)离开屏幕,但屏幕上仍有其他触点(手指)时触发该事件
2案例代码陈列
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.dragscale" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <application android:icon="@drawable/avatar" android:label="@string/app_name" > <activity android:name=".DragScaleMainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application></manifest>
strings.xml
<resources> <string name="app_name">ImageView拖拉与多点触摸缩放</string></resources>
main.xml
<?xml version="1.0" encoding="utf-8" ?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/xianyun4" android:scaleType="matrix" /></LinearLayout>
DragScaleMainActivity.java
package com.android.dragscale;import android.app.Activity;import android.graphics.Matrix;import android.graphics.PointF;import android.os.Bundle;import android.util.FloatMath;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;import android.widget.ImageView;public class DragScaleMainActivity extends Activity { private ImageView imageView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); imageView = (ImageView) findViewById(R.id.imageView); imageView.setOnTouchListener(new OnTouchListener() { // 设置开始点 private PointF startPoint = new PointF(); // 设置图片位置的变换矩阵 private Matrix matrix = new Matrix(); // 设置图片当前位置的变换矩阵 private Matrix currentMatrix = new Matrix(); // 初始化模式参数 private int mode = 0; // 无模式 private static final int NONE = 0; // 拖拉模式 private static final int DRAG = 1; // 缩放模式 private static final int ZOOM = 2; // 开启缩放效果的门槛 private static final float ZOOM_THRESHOLD = 10.0f; // 开始距离 private float startDistance; // 中心点 private PointF middlePoint; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: mode = DRAG; // 记录图片当前的移动位置 currentMatrix.set(imageView.getImageMatrix()); // 记录开始坐标 startPoint.set(event.getX(), event.getY()); break; // 当屏幕上已经有触点(手指),再有手指按下时触发该事件 case MotionEvent.ACTION_POINTER_DOWN: mode = ZOOM; startDistance = getDistance(event); if(startDistance > ZOOM_THRESHOLD) { middlePoint = getMiddlePoint(event); // 记录图片当前的缩放比例 currentMatrix.set(imageView.getImageMatrix()); } break; case MotionEvent.ACTION_MOVE: if(mode == DRAG) { // 获取X轴移动距离 float distanceX = event.getX() - startPoint.x; // 获取Y轴移动距离 float distanceY = event.getY() - startPoint.y; // 在上次移动停止位置的基础上再进行移动 matrix.set(currentMatrix); // 实现图片位置移动 matrix.postTranslate(distanceX, distanceY); } else if(mode == ZOOM) { // 结束距离 float endDistance = getDistance(event); if(endDistance > ZOOM_THRESHOLD) { // 缩放比例 float scale = endDistance / startDistance; matrix.set(currentMatrix); matrix.postScale(scale, scale, middlePoint.x, middlePoint.y); } } break; case MotionEvent.ACTION_UP: // 当手指离开屏幕,但屏幕上仍有其他触点(手指)时触发该事件 case MotionEvent.ACTION_POINTER_UP: mode = 0; break; } imageView.setImageMatrix(matrix); return true; } }); } /** * 计算两点之间的距离 * @param event * @return */ public static float getDistance(MotionEvent event) { //第二个点x、y坐标减去第一个点x、y坐标 float disX = event.getX(1) - event.getX(0); float disY = event.getY(1) - event.getY(0); return FloatMath.sqrt(disX * disX + disY * disY); } /** * 计算两点之间的中间点 * @param event * @return */ public static PointF getMiddlePoint(MotionEvent event) { float midX = (event.getX(0) + event.getX(1)) /2; float midY = (event.getY(0) + event.getY(1)) /2; return new PointF(midX, midY); }}注意:提供一张图片(壁纸)存放于drawable-hdpi文件夹下。
3案例效果展示
- Android应用开发之图片拖拉和多点触摸缩放
- android学习笔记---58_拖拉功能与多点触摸,实现图片的拖拉和缩放功能
- android多点触摸缩放图片
- Android多点触摸实现缩放和拖拽图片
- 多点触摸缩放图片
- android 多点触摸实现图片缩放
- android :多点触摸图片移动缩放
- android 多点触摸实现图片缩放
- android 多点触摸实现图片缩放
- android 多点触摸实现图片缩放
- Android多点触摸交互处理-图片缩放
- android中图片的拖拉和缩放
- Android:拖拉功能与多点触摸
- 26-拖拉功能和多点触摸
- 实现多点触摸缩放图片
- 图片缩放,多点触摸响应
- Android多点触摸缩放图片-android学习之旅(四)
- Android学习笔记_38_图片的拖动、缩放功能和多点触摸
- linux sd卡驱动分析
- HttpHandler 在SharePoint 2010中的应用(转)
- 数据读写SD卡下半部分析
- Linux MMC/SD/SDIO体系结构
- 使用缓存的示例代码
- Android应用开发之图片拖拉和多点触摸缩放
- 黑马程序员----java基础之面向对象(2)
- shell_beginner_001
- CocosBuilder(一)读取简单场景
- jquery中添加和取出表单中 disabled="disabled"
- BAE云搭建Web——Servlet中文乱码
- VMware导致平板电脑固件升级时驱动失败
- Ruby (on Rails) 常用的Gems推荐
- 自定义JSP标签