<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<!-- 定义TextView的文本标签 -->
<TextView
android:id="@+id/Tv"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="点击屏幕,隐藏或显示导航栏!" />
</RelativeLayout>
MyView.java
package com.example.yanlei.yl;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.DisplayMetrics;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.widget.ImageView;
//自定义MyView类继承自ImageView
public class MyView extends ImageView {
private float x_down = 0;
private float y_down = 0;
//起始点的坐标
private PointF start = new PointF();
//中心点的坐标
private PointF mid = new PointF();
private float oldDist = 1f;
private float oldRotation = 0;
private Matrix matrix = new Matrix();
private Matrix matrix1 = new Matrix();
private Matrix savedMatrix = new Matrix(); private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private int mode = NONE; private boolean matrixCheck = false; //记录当前屏幕的宽度
private int widthScreen;
//记录当前屏幕的高度
private int heightScreen; //在页面中显示的Bitmap图片
private Bitmap kenan; public MyView(Activity activity) {
super(activity);
//通过Bitampfactory读取drawable目录下的kenan资源
kenan = BitmapFactory.
decodeResource(getResources(), R.drawable.kenan); //定义图片一个显示矩阵
DisplayMetrics dm = new DisplayMetrics();
//得到当前屏幕的显示矩阵存入dm变量
activity.getWindowManager().
getDefaultDisplay().getMetrics(dm);
//通过显示矩阵得到当前屏幕的宽度和高度的像素值
widthScreen = dm.widthPixels;
heightScreen = dm.heightPixels; matrix = new Matrix();
} //显示view的时候回调onDraw
protected void onDraw(Canvas canvas) {
//首先保存当前页面已有的图像
canvas.save();
//按照当前的矩阵绘制kenan图片
canvas.drawBitmap(kenan, matrix, null);
//画图板恢复
canvas.restore();
} //当用户触摸此视图的时候回调次方法
public boolean onTouchEvent(MotionEvent event) {
//得到touch的事件类型
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
//当按下屏幕时,记录当前的状态为拖动
mode = DRAG;
//记录xy坐标
x_down = event.getX();
y_down = event.getY();
//保存当前的矩阵
savedMatrix.set(matrix);
break;
case MotionEvent.ACTION_POINTER_DOWN:
//多个手指触摸的状态
mode = ZOOM;
//记录之前的两手指间距
oldDist = spacing(event);
//记录之前的角度
oldRotation = rotation(event);
//保存当前的图片矩阵
savedMatrix.set(matrix);
//得到旋转的中心点
midPoint(mid, event);
break;
case MotionEvent.ACTION_MOVE:
//当手指移动时的状态
if (mode == ZOOM) {
//缩放并且平移
matrix1.set(savedMatrix);
//得到旋转的角度
float rotation =
rotation(event) - oldRotation;
//得到距离
float newDist = spacing(event);
//得到放大倍数
float scale = newDist / oldDist;
//缩放倍数
matrix1.postScale(scale, scale, mid.x, mid.y);
//得到旋转角度
matrix1.postRotate(rotation, mid.x, mid.y);
//得到图片是否出边界
matrixCheck = matrixCheck();
if (matrixCheck == false) {
matrix.set(matrix1);
invalidate();
}
} else if (mode == DRAG) {
//平行移动
matrix1.set(savedMatrix);
matrix1.postTranslate(event.getX() - x_down
, event.getY() - y_down);// 平移
matrixCheck = matrixCheck();
matrixCheck = matrixCheck();
if (matrixCheck == false) {
matrix.set(matrix1);
invalidate();
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
}
return true;
} //对图片的矩阵进行检测
private boolean matrixCheck() {
float[] f = new float[9];
matrix1.getValues(f);
// 图片4个顶点的坐标
float x1 = f[0] * 0 + f[1] * 0 + f[2];
float y1 = f[3] * 0 + f[4] * 0 + f[5];
float x2 = f[0] * kenan.getWidth()
+ f[1] * 0 + f[2];
float y2 = f[3] * kenan.getWidth()
+ f[4] * 0 + f[5];
float x3 = f[0] * 0 + f[1] *
kenan.getHeight() + f[2];
float y3 = f[3] * 0 + f[4] *
kenan.getHeight() + f[5];
float x4 = f[0] * kenan.getWidth() +
f[1] * kenan.getHeight() + f[2];
float y4 = f[3] * kenan.getWidth() +
f[4] * kenan.getHeight() + f[5];
// 图片现宽度
double width = Math.sqrt((x1 - x2) *
(x1 - x2) + (y1 - y2) * (y1 - y2));
// 缩放比率判断
if (width < widthScreen / 3 || width > widthScreen * 3) {
return true;
}
// 出界判断
if ((x1 < widthScreen / 3 && x2 < widthScreen / 3
&& x3 < widthScreen / 3
&& x4 < widthScreen / 3)
|| (x1 > widthScreen * 2 / 3
&& x2 > widthScreen * 2 / 3
&& x3 > widthScreen * 2 / 3
&& x4 > widthScreen * 2 / 3)
|| (y1 < heightScreen / 3
&& y2 < heightScreen / 3
&& y3 < heightScreen / 3
&& y4 < heightScreen / 3)
|| (y1 > heightScreen * 2 / 3
&& y2 > heightScreen * 2 / 3
&& y3 > heightScreen * 2 / 3
&& y4 > heightScreen * 2 / 3)) {
return true;
}
return false;
} // 触碰两点间距离
private float spacing(MotionEvent event) {
//通过三角函数得到两点间的距离
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
} // 取手势中心点
private void midPoint(PointF point, MotionEvent event) {
//得到手势中心点的位置
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
} // 取旋转角度
private float rotation(MotionEvent event) {
//得到两个手指间的旋转角度
double delta_x = (event.getX(0) - event.getX(1));
double delta_y = (event.getY(0) - event.getY(1));
double radians = Math.atan2(delta_y, delta_x);
return (float) Math.toDegrees(radians);
}
}
MainActivity
package com.example.yanlei.yl;

import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.text.Html;
import android.text.Html.ImageGetter; import java.util.regex.Matcher;
import java.util.regex.Pattern; import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import android.widget.Button; import android.app.Activity;
import android.content.Intent; import android.view.MotionEvent;
import android.widget.TextView;
import android.view.Window;
import android.view.WindowManager; public class MainActivity extends AppCompatActivity {
//定义TextView对象
private TextView Tv; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//定义自定义View的对象
MyView myview = new MyView(this);
//设置当前页面的视图为自定义的myview
setContentView(myview); } }

android 图片的平移,缩放和旋转的更多相关文章

  1. Android 图片的平移和镜面和倒影效果

    在前面的文章中陆续介绍了图片的旋转与缩放,本文继续介绍关于图片的操作 图片的平移 使用下面的代码将图水平竖直方向平移10个像素 matrix.setTranslate(10, 10); 可以看到图片不 ...

  2. 使用C#进行图片转换格式,缩放,自动旋转,保留exif(转载)

    这几天心血来潮做了一个批量图片缩放,转换格式,并且可以根据exif的信息旋转图片,校正exif信息后保存的小程序.根据配置文件 指定需要的功能. 1 2 3 4 5 6 7 8 9 10 11 12 ...

  3. 23.Quick QML-简单且好看的图片浏览器-支持多个图片浏览、缩放、旋转、滑轮切换图片

    之前我们已经学习了Image.Layout布局.MouseArea.Button.GroupBox.FileDialog等控件. 所以本章综合之前的每章的知识点,来做一个图片浏览器,使用的Qt版本为Q ...

  4. android图片透明度跟缩放大小动画事件

    概序 : 动画事件写在xml中,然后用AnimationUtils去加载动画事件,再监听动画结束事件,隐藏imageview. 1. player_double_click_animation.xml ...

  5. android图片等比例缩放 填充屏幕

    在ImageView的t同事设置两个属性 android:adjustViewBounds="true"android:scaleType="fitXY"

  6. Android图片旋转,缩放,位移,倾斜,对称完整示例(一)——imageView.setImageMatrix(matrix)和Matrix

    MainActivity如下: import android.os.Bundle; import android.view.MotionEvent; import android.view.View; ...

  7. Android图片旋转,缩放,位移,倾斜,对称完整演示样例(一)——imageView.setImageMatrix(matrix)和Matrix

    MainActivity例如以下: import android.os.Bundle; import android.view.MotionEvent; import android.view.Vie ...

  8. Android动画及图片的缩放和旋转

    Android动画有2种,一种是Tween Animation,另一种是Frame Animation,先说说Tween动画吧. Tween动画是对视图对象中的内容进行一系列简单的转换,比如位置的移动 ...

  9. 【C#/WPF】Image图片的Transform变换:平移、缩放、旋转

    WPF中图像控件Image的变换属性Transform: 平移 缩放 旋转 即要想实现图片的平移.缩放.旋转,是修改它所在的Image控件的Transform变换属性. 下面在XAML中定义了Imag ...

随机推荐

  1. CF-1082(渣渣只做了前三个)

    链接:http://codeforces.com/contest/1082 A. Vasya and Book 题意: n,x,y,d 一本电子书有n页,每一次翻动只能往前或者往后翻d页.求x-> ...

  2. 【OS_Linux】yum命令安装软件

    1.YUM的简介 Yum(全称为 Yellow dog Updater, Modified)是一个rpm包管理器.它能够从指定的服务器上自动下载RPM包并安装,可以自动处理包之间的依赖性关系,并且一次 ...

  3. 【git】不检查特定文件的更改情况

    .gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的.正确的做法是在每个clone下来的仓库中手动设置不要检查特定文件的更 ...

  4. Python_编程题集_001_词法解析

    1.词法解析: 我的是名字是ths,今年18岁 语法分析后得到结果如下: 数字:18 中文:我的名字是 今年 岁 拼音:ths 符号:,. 请编写程序实现该词法分析功能 string模块解: impo ...

  5. 微信小程序登录对接Django后端实现JWT方式验证登录

    先上效果图 点击授权按钮后可以显示部分资料和头像,点击修改资料可以修改部分资料. 流程 1.使用微信小程序登录和获取用户信息Api接口 2.把Api获取的用户资料和code发送给django后端 3. ...

  6. LeetCode(119) Pascal's Triangle II

    题目 Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3, Return [ ...

  7. python基础学习笔记——collections模块

    在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter.deque.defaultdict.namedtuple和Ord ...

  8. luogu3396 哈希冲突

    参考这里 我们先预处理模数在 \(\sqrt{n}\) 以内的询问. 要是模数在 \(\sqrt{n}\) 以外,直接暴力统计,反正这样的数又不会超过 \(\sqrt{n}\) 个. 修改的时候也是. ...

  9. 面试准备——java设计模式

    1 总体来说,设计模式分为三大类: 设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案. 创建型模式(五种):工厂方法模式.抽象工厂模式.单例模式. ...

  10. shell-001

    for: shell_test #!/bin/bash var= var=$var+ echo $var mkdir only_a_joke shell_joke #!/bin/bash ./shel ...