我是靠谱客的博主 朴素微笑,最近开发中收集的这篇文章主要介绍Android中实现双指缩放的功能,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Android中实现双指缩放的功能

安卓中实现将图片缩放的功能提供了一个很好的类:ScaleGestureDetector,本章就介绍使用canvas和ScaleGestureDetector类实现缩放的功能,如果要想详细了解ScaleGestureDetector请参考博文Android的ScaleGestureDetector缩放类详解
1. 先初始化缩放比和图片居中绘制的坐标点

	float posX, posY;
//图片的坐标
int viewWidth, viewHeight;
//屏幕的宽高
float widthScale, heightScale;
//宽高缩放比
boolean hasInitViewSize;
//是否已经初始化视图
public void initSize() {
viewWidth = getWidth();
//得到屏幕宽度
viewHeight = getHeight();
//得到屏幕高度
if (viewWidth < 0 && viewHeight < 0) {
return;
}
hasInitViewSize = true;
widthScale = viewWidth / imgWidth;
//宽高缩放比=屏幕的宽高/屏幕的宽高
heightScale = viewHeight / imgHeight;
scaleFactor = Math.min(widthScale, heightScale);	//总缩放比取宽高缩放比中最小的
posX = viewWidth / 2 - imgWidth / 2;
//使图片居中绘制
posY = viewHeight / 2 - imgHeight / 2;
}

2. 创建两个内部类分别继承SimpleOnScaleGestureListener和SimpleOnGestureListener来动态获取缩放比和坐标

class MySimpleOnGestureDetector extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
posX -= distanceX;
//X轴的坐标=X轴的坐标-在X轴方向的移动距离
posY -= distanceY;
//y轴的坐标=y轴的坐标-在y轴方向的移动距离
invalidate();
//刷新view
return true;
}
}
class MySimpleScaleOnGestureDetector extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
scaleFactor *= detector.getScaleFactor();
//缩放比=缩放比*动态获取的缩放比
scaleFactor = scaleFactor < 0.75 ? (float) 0.75 : scaleFactor > 3 ? 3 : scaleFactor;	//控制缩放倍率在0.75-3之间
invalidate();
//刷新view
return true;
}
}

3. 为了移动图片时不超出屏幕,还得进行控制,原则是:图片较小时任意一条边都不能出了边界,图片较大任意一条边都不能进入边界。宽度和高度分别独立计算。

public void checkBounds() {
if (scaleFactor > widthScale) {	//宽度方向已经填满
posX = Math.min(posX, (scaleFactor - 1) * (imgWidth / 2));
posX = Math.max(posX, viewWidth - imgWidth - (scaleFactor - 1) * (imgWidth / 2));
} else {
posX = Math.max(posX, (scaleFactor - 1) * (imgWidth / 2));
posX = Math.min(posX, viewWidth - imgWidth - (scaleFactor - 1) * (imgWidth / 2));
}
if (scaleFactor > heightScale) {	//高度方向已经填满
posY = Math.min(posY, (scaleFactor - 1) * (imgHeight / 2));
posY = Math.max(posY, viewHeight - imgHeight - (scaleFactor - 1) * (imgHeight / 2));
} else {
posY = Math.max(posY, (scaleFactor - 1) * (imgHeight / 2));
posY = Math.min(posY, viewHeight - imgHeight - (scaleFactor - 1) * (imgHeight / 2));
}
}

4. 在类中实现onDraw方法进行绘制缩放

 @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (bitmap == null) {
return;
}
if (!hasInitViewSize) {
initSize();
}
canvas.save();	//画布保存
checkBounds();	//检查边界,使图片不能超出屏幕
canvas.scale(scaleFactor, scaleFactor, posX + imgWidth / 2, posY + imgHeight / 2);	///以图片的中心为基点进行缩放
canvas.drawBitmap(bitmap, posX, posY, paint);	//绘制图片
canvas.restore();	//画布重绘
}

5. 关键点已经差不多写完了,现在将完整的类写上

package com.example.mygesture;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
public class MyScaleView extends View {
ScaleGestureDetector scaleGestureDetector;
float scaleFactor;
float posX, posY;
int viewWidth, viewHeight;
float widthScale, heightScale;
boolean hasInitViewSize;
Paint paint = new Paint();
Bitmap bitmap;
float imgWidth, imgHeight;
GestureDetector gestureDetector;
public MyScaleView(Context context, @Nullable AttributeSet attrs) {	//注意:得在有两个参数的构造函数中实例化ScaleGestureDetector 和GestureDetector 
super(context, attrs);
init(context);
}
private void init(Context context) {
scaleGestureDetector = new ScaleGestureDetector(context, new MySimpleScaleOnGestureDetector());
gestureDetector = new GestureDetector(context, new MySimpleOnGestureDetector());
}
class MySimpleOnGestureDetector extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
posX -= distanceX;
posY -= distanceY;
invalidate();
return true;
}
}
class MySimpleScaleOnGestureDetector extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
scaleFactor *= detector.getScaleFactor();
scaleFactor = scaleFactor < 0.75 ? (float) 0.75 : scaleFactor > 3 ? 3 : scaleFactor;
invalidate();
return true;
}
}
public void initSize() {
viewWidth = getWidth();
viewHeight = getHeight();
if (viewWidth < 0 && viewHeight < 0) {
return;
}
hasInitViewSize = true;
widthScale = viewWidth / imgWidth;
heightScale = viewHeight / imgHeight;
scaleFactor = Math.min(widthScale, heightScale);
posX = viewWidth / 2 - imgWidth / 2;
posY = viewHeight / 2 - imgHeight / 2;
}
public void checkBounds() {
//检查边界
if (scaleFactor > widthScale) {
posX = Math.min(posX, (scaleFactor - 1) * (imgWidth / 2));
posX = Math.max(posX, viewWidth - imgWidth - (scaleFactor - 1) * (imgWidth / 2));
} else {
posX = Math.max(posX, (scaleFactor - 1) * (imgWidth / 2));
posX = Math.min(posX, viewWidth - imgWidth - (scaleFactor - 1) * (imgWidth / 2));
}
if (scaleFactor > heightScale) {
posY = Math.min(posY, (scaleFactor - 1) * (imgHeight / 2));
posY = Math.max(posY, viewHeight - imgHeight - (scaleFactor - 1) * (imgHeight / 2));
} else {
posY = Math.max(posY, (scaleFactor - 1) * (imgHeight / 2));
posY = Math.min(posY, viewHeight - imgHeight - (scaleFactor - 1) * (imgHeight / 2));
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
scaleGestureDetector.onTouchEvent(event);	//双指缩放
gestureDetector.onTouchEvent(event);
//单指移动
return true;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (bitmap == null) {
return;
}
if (!hasInitViewSize) {
initSize();
}
canvas.save();
checkBounds();
canvas.scale(scaleFactor, scaleFactor, posX + imgWidth / 2, posY + imgHeight / 2);
canvas.drawBitmap(bitmap, posX, posY, paint);
canvas.restore();
}
public void setImageResouse(int resID) {	//设置图片
bitmap = BitmapFactory.decodeResource(getResources(), resID);
imgWidth = bitmap.getWidth();
imgHeight = bitmap.getHeight();
initSize();
invalidate();
}
}

6. 类已经写好了,现在对其使用,创建一个新的Activity

6.1 构造布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".text.Main8Activity">
<com.example.mygesture.MyScaleView
android:id="@+id/activity_main8_myScaleView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

6.2 对应的类中

package com.example.mygesture.text;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.example.mygesture.MyScaleView;
import com.example.mygesture.R;
public class Main8Activity extends AppCompatActivity {
MyScaleView myScaleView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main8);
myScaleView = findViewById(R.id.activity_main8_myScaleView);
myScaleView.setImageResouse(R.drawable.q4);
}
}

7. 所以使用还是很简单的,因为缩放操作模拟器上不好演示,效果图就省略了。

Tip: 小白,写得不好请见谅。若有不对的地方请留言。

关于手势方面的功能点还可以参考Android中实现自定义手势和识别手势的功能,Android中简单实现页面翻转和自动翻转的功能

最后

以上就是朴素微笑为你收集整理的Android中实现双指缩放的功能的全部内容,希望文章能够帮你解决Android中实现双指缩放的功能所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部