//在main中的布局
//在ViewPager的item中的布局
//自定义ImageView
import android.R.bool;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.OnScaleGestureListener;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.ImageView;
import android.view.View.OnTouchListener;
public class ZoomImageView extends ImageView implements OnGlobalLayoutListener, OnScaleGestureListener,OnTouchListener{
private boolean mOnce = false;
//初始化缩放的值
private float mInitScale;
//双击放大值到达的值
private float mMidScale;
//放大的最大值
private float mMaxScale;
private Matrix mScaleMatrix;
//捕获用户多指触控时缩放的比例‘
private ScaleGestureDetector mScaleGestureDetector;
//====================图片自由移动
private int mLastPointerCount;//记录上一次多点触控的数量
private float mLastX;
private float mLastY;//记录最后一次x,y的坐标
private int mTouchSlop;//获取系统的值
private boolean isCanDrag;
//判断 控件左右,上下是否超出
private boolean isCheckLeftAndRight;
private boolean isCheckTopAndBottom;
//==========双击放大与缩小
private GestureDetector mGestureDetector;
private boolean isAutoScale;
public ZoomImageView(Context context) {
super(context);
}
public ZoomImageView(Context context, AttributeSet attrs) {
super(context, attrs);
mScaleMatrix = new Matrix();
mScaleGestureDetector = new ScaleGestureDetector(context, this);
setOnTouchListener(this);
//图片自由移动时,获取的系统的值
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mGestureDetector = new GestureDetector(context,
new GestureDetector.SimpleOnGestureListener(){
public boolean onDoubleTap(MotionEvent e) {
//如果用户已经点击过了,并且此时正在放大或者缩小,就不让点击
if(isAutoScale)
return true;
//当前点击的x,y的坐标,已点击的点为屏幕的中心点
float x = e.getX();
float y = e.getY();
if(getScale()
mTargetScale){//缩小
tmpScale = SMALL;
}
}
public void run() {
//进行缩放
mScaleMatrix.postScale(tmpScale, tmpScale, x, y);
checkBorderAndCenterWhenScale();
setImageMatrix(mScaleMatrix);
float currentScale = getScale();
if(tmpScale >1.0f&¤tScale
mTargetScale){
//每16毫秒执行一次这个方法
postDelayed(this, 50);
}else{//设置为我们的目标值
float scale = mTargetScale/currentScale;
mScaleMatrix.postScale(scale, scale, x, y);
checkBorderAndCenterWhenScale();
setImageMatrix(mScaleMatrix);
isAutoScale = false;
}
}
}
//全局布局完成之后,会执行这样一个方法
//获得ImagerView加载完成的图片
public void onGlobalLayout() {
//保证只会进行一次的比较
if(!mOnce){
//获得控件的宽高
//一般控件的宽高,就是屏幕的宽高
int wight = getWidth();
int height = getHeight();
//得到我们的图片,以及宽和高
Drawable d = getDrawable();
if(d == null){
return ;
}
int dw = d.getIntrinsicWidth();
int dh = d.getIntrinsicHeight();
//设置一个缩放值
float scale = 1.0f;
//如果图片的宽度大于控件的宽度,高度小于控件的宽高,那么将其缩放
if(dw>wight && dh
height){
scale = height*1.0f/dh;
}
//宽高均小于控件宽高,宽高均大于控件宽高,将其缩放或扩大
if((dw>wight && dh>height)||(dw
1.0f)||(scale>mInitScale&&scaleFactor<1.0f)){
//当你想缩的特别小时,我们就将mInitScale设置给你
if(scale*scaleFactor < mInitScale){
scaleFactor = mInitScale/scale;
}
//当你想放的特别大时,我们就将mMaxScale设置给你
if(scale*scaleFactor > mMaxScale){
scaleFactor = mMaxScale/scale;
}
//缩放中心点
mScaleMatrix.postScale(scaleFactor, scaleFactor,detector.getFocusX(),detector.getFocusY());
//在缩放的时候,进行边界的控制,以及我们的位置的控制
checkBorderAndCenterWhenScale();
setImageMatrix(mScaleMatrix);
}
return true;
}
public boolean onScaleBegin(ScaleGestureDetector detector) {
//必须将返回值改为true;
return true;
}
public void onScaleEnd(ScaleGestureDetector detector) {
}
//RectF是一个矩形,里边所有的值是浮点型
//获得图片放大缩小以后的宽和高,以及left,right,top,buttom
private RectF getMatrixRectF(){
Matrix matrix = mScaleMatrix;
RectF rectF = new RectF();
Drawable d = getDrawable();
if(d != null){
rectF.set(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
matrix.mapRect(rectF);
}
return rectF;
}
//在缩放的时候,进行边界的控制,以及我们的位置的控制
private void checkBorderAndCenterWhenScale() {
//调用 getMatrixRectF()获得RectF
RectF rect = getMatrixRectF();
//左边和右边的差值
float deltaX = 0;
float deltaY = 0;
//宽高
int width = getWidth();
int height = getHeight();
//缩放时,进行边界测试,放置出现白边
//rect.width()是通过放大缩小之后的图片的宽度
//水平方向上的控制
if(rect.width() >= width){
if(rect.left>0){
deltaX = -rect.left;
}
if(rect.right
=height){ if(rect.top>0){ deltaY = -rect.top; } if(rect.bottom
getWidth()+0.01||rectF1.height()>getHeight()+0.01){ getParent().requestDisallowInterceptTouchEvent(true); } case MotionEvent.ACTION_MOVE: if(rectF1.width()>getWidth()+0.01||rectF1.height()>getHeight()+0.01){ getParent().requestDisallowInterceptTouchEvent(true); } //记录x,y的偏移量(这次的中心点坐标减去上次中心点的坐标) float dx = x-mLastX; float dy = y-mLastY; //在手指触控的个数发生变化,但是又想移动图片时,去判断,移动的偏移量是否足以触发移动 if(!isCanDrag){ isCanDrag = isMoveAction(dx, dy); } //移动过程的一个操作 if(isCanDrag){ RectF rectF = getMatrixRectF(); if(getDrawable() != null){ //每次都去检测图片 isCheckLeftAndRight = isCheckTopAndBottom = true; //如果宽度小于控件宽度 ,不允许横向移动(说明此图片横向上已完全显示) if(rectF.width()
0 && isCheckTopAndBottom){ deltaY = -rectF.top; } //底部不能出现 白边 if(rectF.bottom
0 && isCheckLeftAndRight){ deltaX = -rectF.left; } //右边不能出现白边 if(rectF.right
mTouchSlop; } } //在mainAcitity中 import com.example.view.ZoomImageView; import android.os.Bundle; import android.app.Activity; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.view.Menu; import android.view.View; import android.view.ViewGroup; import android.widget.ZoomButton; public class MainActivity extends Activity { private ViewPager mViewPager; private int [] mImgs = new int[]{R.drawable.af,R.drawable.ae,R.drawable.ah}; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mViewPager = (ViewPager) findViewById(R.id.view_pager); mViewPager.setAdapter(new PagerAdapter() { public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } public int getCount() { return mImgs.length; } public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View)object); } public Object instantiateItem(ViewGroup container, int position) { View view = View.inflate(MainActivity.this, R.layout.vp, null); ZoomImageView imageView = (ZoomImageView) view.findViewById(R.id.zv); imageView.setImageResource(mImgs[position]); container.addView(view); return view; } }); } }
自定义viewpager,实现图片多指触控,双击,放大或缩小,和viewpager的冲突
最新推荐文章于 2021-11-17 17:07:46 发布
本文介绍了如何自定义ViewPager,实现图片的多指触控缩放以及双击图片放大或缩小的功能。同时,讨论了在实现过程中可能遇到的与ViewPager原有滑动冲突的问题,提供了解决方案。
摘要由CSDN通过智能技术生成