Android实现 通过手势随意缩放、移动ImageView图片
在这里,我对自己的笔记本全屏截图,然后当作自定义ImageView的src内容放在真机上运行。
可以看到这里的图片是可以移动和缩放的。
在这里先说清一点,如果在xml的控件上设置src,则需要在代码上通过getDrawable();获取,如果是通过setBackGround的,则通过getBackground();获取即可。
publicclassMyImageViewextendsImageViewimplementsScaleGestureDetector.OnScaleGestureListener,
- View.OnTouchListener{ 这个是我自定义ImageView的类名。
/**
*控件宽度
*/
privateintmWidth;
/**
*控件高度
*/
privateintmHeight;
/**
*拿到src的图片
*/
privateDrawablemDrawable;
/**
*图片宽度(使用前判断mDrawable是否null)
*/
privateintmDrawableWidth;
/**
*图片高度(使用前判断mDrawable是否null)
*/
privateintmDrawableHeight;
/**
*初始化缩放值
*/
privatefloatmScale;
/**
*双击图片的缩放值
*/
privatefloatmDoubleClickScale;
/**
*最大的缩放值
*/
privatefloatmMaxScale;
/**
*最小的缩放值
*/
privatefloatmMinScale;
privateScaleGestureDetectorscaleGestureDetector;
/**
*当前有着缩放值、平移值的矩阵。
*/
privateMatrixmatrix;
这些是我定义出来的一些成员变量,每个变量我都写上了作用。
publicMyImageView(Contextcontext){
this
(context,
null
);
}
publicMyImageView(Contextcontext,AttributeSetattrs){
this
(context,attrs,
0
);
}
publicMyImageView(Contextcontext,AttributeSetattrs,intdefStyleAttr){
super
(context,attrs,defStyleAttr);
setOnTouchListener(
this
);
scaleGestureDetector=newScaleGestureDetector(context,
this
);
initListener();
}
这里是三个标准的构造器,直接用短的引用长的就是了。
先看一看initListener();干了什么事情。
- /**
- *初始化事件监听
- */
- privatevoidinitListener(){
- //强制设置模式
- setScaleType(ScaleType.MATRIX);
- //添加观察者
- getViewTreeObserver().addOnGlobalLayoutListener(newViewTreeObserver.OnGlobalLayoutListener(){
- @Override
- publicvoidonGlobalLayout(){
- //移除观察者
- getViewTreeObserver().removeOnGlobalLayoutListener(this);
- //获取控件大小
- mWidth=getWidth();
- mHeight=getHeight();
- //通过getDrawable获得Src的图片
- mDrawable=getDrawable();
- if(mDrawable==null)
- return;
- mDrawableWidth=mDrawable.getIntrinsicWidth();
- mDrawableHeight=mDrawable.getIntrinsicHeight();
- initImageViewSize();
- moveToCenter();
- }
- });
- }
- /**
- *初始化资源图片宽高
- */
- privatevoidinitImageViewSize(){
- if(mDrawable==null)
- return;
- //缩放值
- floatscale=1.0f;
- //图片宽度大于控件宽度,图片高度小于控件高度
- if(mDrawableWidth>mWidth&&mDrawableHeight<mheight)
- scale=mWidth*1.0f/mDrawableWidth;
- //图片高度度大于控件宽高,图片宽度小于控件宽度
- elseif(mDrawableHeight>mHeight&&mDrawableWidth<mwidth)
- scale=mHeight*1.0f/mDrawableHeight;
- //图片宽度大于控件宽度,图片高度大于控件高度
- elseif(mDrawableHeight>mHeight&&mDrawableWidth>mWidth)
- scale=Math.min(mHeight*1.0f/mDrawableHeight,mWidth*1.0f/mDrawableWidth);
- //图片宽度小于控件宽度,图片高度小于控件高度
- elseif(mDrawableHeight<mheight&&mdrawablewidth<mwidth)
- scale=Math.min(mHeight*1.0f/mDrawableHeight,mWidth*1.0f/mDrawableWidth);
- mScale=scale;
- mMaxScale=mScale*8.0f;
- mMinScale=mScale*0.5f;
- }
先判断一下有没有src资源,没有的话,这个方法调用也没意义了。
- /**
- *移动控件中间位置
- */
- privatevoidmoveToCenter(){
- finalfloatdx=mWidth/2-mDrawableWidth/2;
- finalfloatdy=mHeight/2-mDrawableHeight/2;
- matrix=newMatrix();
- //平移至中心
- matrix.postTranslate(dx,dy);
- //以控件中心作为缩放
- matrix.postScale(mScale,mScale,mWidth/2,mHeight/2);
- setImageMatrix(matrix);
- }
dx的意思是取横方向上,控件中心到图片中心的值,如果大于0就向右移动,
反之向左移动相应的绝对值。
dy则换成纵向方向就是了。
在这里实例化了matrix对象(初始化一次就行),至于为什么只需要初始化一次,
因为图片的缩放值和平移值,都是通过matrix保存的,如果再一次初始化,缩放值
和平移值等等数据都会被清空。
我是先让它平时到控件正中心,然后以控件中心缩放mScale,mScale在initImageViewSize();的时候已经赋值了。
至于先缩放后平移,应该也是可以得,但可能计算公式相对麻烦些,
在这里本着方便为主的原则,就不再作计算了。
接下来会说到这个东西scaleGestureDetector = new ScaleGestureDetector(context, this);
通过这个方法,实现了监听事件,是手势滑动的监听事件。
[java]view plaincopy
- @Override
- publicbooleanonScale(ScaleGestureDetectordetector){
- returntrue;
- }
- @Override
- publicbooleanonScaleBegin(ScaleGestureDetectordetector){
- returntrue;
- }
- @Override
- publicvoidonScaleEnd(ScaleGestureDetectordetector){
- }
但是,虽然实现了监听,但是然并卵,因为onTouch事件中没有它(scaleGestureDetector),在这里 ,重写onTouchEvent是没用的,因为onTouchEventListener的优先级比onTouchEvent要高,所以我们只能这样子。
- setOnTouchListener(this);
- @Override
- publicbooleanonTouch(Viewv,MotionEventevent){
- returnscaleGestureDetector.onTouchEvent(event);
- }
然后手势生效了(呵呵哒
![](http://www.2cto.com/uploadfile/Collfiles/20160614/20160614093440133.gif)
- @Override
- publicbooleanonScaleBegin(ScaleGestureDetectordetector){
- returntrue;
- }
这个方法是手势执行前生效,必须return ture,不然onScale必定失效!
现在重点说一下onScale,因为这个方法是处理手势的缩放,
- @Override
- publicbooleanonScale(ScaleGestureDetectordetector){
- if(mDrawable==null){
- returntrue;
- }
- //系统定义的缩放值
- floatscaleFactor=detector.getScaleFactor();
- //获取已经缩放的值
- floatscale=getmScale();
- floatscaleResult=scale*scaleFactor;
- if(scaleResult>=mMaxScale&&scaleFactor>1.0f)
- scaleFactor=mMaxScale/scale;
- if(scaleResult<=mMinScale&&scaleFactor<1.0f)
- scaleFactor=mMinScale/scale;
- matrix.postScale(scaleFactor,scaleFactor,detector.getFocusX(),detector.getFocusY());
- /
- setImageMatrix(matrix);
- }
其中,scaleFactor是获得手势缩放的值(具体怎么获取的不知道),当值>1.0f时,说明两个手指的滑动距离是不断增加(相对于两个手指都down了的那一瞬间),同理<1.0f说明两个手指的滑动距离不断减少,也是相对于那一瞬间,
- /**
- *@return当前缩放的值
- */
- privatefloatgetmScale(){
- float[]floats=newfloat[9];
- matrix.getValues(floats);
- returnfloats[Matrix.MSCALE_X];
- }
通过这个方法 ,拿到了之前matrix对象的scaleX值(X和Y都没所谓,因为在这里都是一个值),然后将当前的scale*手势滑动的缩放值,得到最新的缩放值scaleResult,在这里做了一个最大放大值和最小缩小值得处理,如果scaleResult大于等于最大缩放值和手指滑动为放大手势,则让手势缩放为一个恒定的最大放大值(反之同理)。
看效果图后,会觉得比较奇葩,因为缩小的时候,位置好像偏了!(原本是在控件正中心)。
- /**
- *@parammatrix矩阵
- *@returnmatrix的ltbr和width,height
- */
- privateRectFgetRectf(Matrixmatrix){
- RectFf=newRectF();
- if(mDrawable==null)
- returnnull;
- f.set(0,0,mDrawableWidth,mDrawableHeight);
- matrix.mapRect(f);
- returnf;
- }
首先看一下这个方法,通过这个方法,可以得到矩阵matrix的N维属性,并把这N维属性赋值到一个float类型的矩形上。
在将上面的/。。。补上
- RectFf=getRectf(matrix);
- floatdX=0.0f;
- floatdY=0.0f;
- //图片高度大于控件高度
- if(f.height()>=mHeight){
- //图片顶部出现空白
- if(f.top>0){
- //往上移动
- dY=-f.top;
- }
- //图片底部出现空白
- if(f.bottom<mheight){
- //往下移动
- dY=mHeight-f.bottom;
- }
- }
- //图片宽度大于控件宽度
- if(f.width()>=mWidth){
- //图片左边出现空白
- if(f.left>0){
- //往左边移动
- dX=-f.left;
- }
- //图片右边出现空白
- if(f.right<mwidth){
- //往右边移动
- dX=mWidth-f.right;
- }
- }
- if(f.width()<mwidth){
- dX=mWidth/2-f.right+f.width()/2;
- }
- if(f.height()<mheight){
- dY=mHeight/2-f.bottom+f.height()/2;
- }
- matrix.postTranslate(dX,dY);
- setImageMatrix(matrix);
首先获取矩阵matrix的N维并赋值在f身上。[java]view plaincopy
- //图片高度大于控件高度
- if(f.height()>=mHeight){
- //图片顶部出现空白
- if(f.top>0){
- //往上移动
- dY=-f.top;
- }
- //图片底部出现空白
- if(f.bottom<mheight){
- //往下移动
- dY=mHeight-f.bottom;
- }
- }
![](http://www.2cto.com/uploadfile/Collfiles/20160614/20160614093441135.png)
大概就是这个意思:当图片高度大于等于控件高度的时候,坚决不让控件高度方向上出现白色位置,此时,假设当图片和控件高度完全相同的时候,是不是图片的纵向刚好和控件完全重叠呢?[java]view plaincopy
- if(f.height()<mheight){
- dY=mHeight/2-f.bottom+f.height()/2;
- }
![](http://www.2cto.com/uploadfile/Collfiles/20160614/20160614093441136.png)
[java]view plaincopy
- privatefloatdownX;
- privatefloatdownY;
- privatefloatnowMovingX;
- privatefloatnowMovingY;
- privatefloatlastMovedX;
- privatefloatlastMovedY;
- privatebooleanisFirstMoved=false;
- @Override
- publicbooleanonTouch(Viewv,MotionEventevent){
- switch(event.getAction()&MotionEvent.ACTION_MASK){
- caseMotionEvent.ACTION_DOWN:
- isFirstMoved=false;
- downX=event.getX();
- downY=event.getY();
- break;
- caseMotionEvent.ACTION_POINTER_DOWN:
- isFirstMoved=false;
- break;
- caseMotionEvent.ACTION_MOVE:
- nowMovingX=event.getX();
- nowMovingY=event.getY();
- if(!isFirstMoved){
- isFirstMoved=true;
- lastMovedX=nowMovingX;
- lastMovedY=nowMovingY;
- }
- floatdX=0.0f;
- floatdY=0.0f;
- RectFrectf=getRectf(matrix);
- //判断滑动方向
- finalfloatscrollX=nowMovingX-lastMovedX;
- //判断滑动方向
- finalfloatscrollY=nowMovingY-lastMovedY;
- //图片高度大于控件高度
- if(rectf.height()>mHeight&&canSmoothY()){
- dY=nowMovingY-lastMovedY;
- }
- //图片宽度大于控件宽度
- if(rectf.width()>mWidth&&canSmoothX()){
- dX=nowMovingX-lastMovedX;
- }
- matrix.postTranslate(dX,dY);
- remedyXAndY(dX,dY);
- lastMovedX=nowMovingX;
- lastMovedY=nowMovingY;
- break;
- caseMotionEvent.ACTION_UP:
- break;
- caseMotionEvent.ACTION_POINTER_UP:
- isFirstMoved=false;
- break;
- }
- returnscaleGestureDetector.onTouchEvent(event);
- }
MotionEvent.ACTION_POINTER_DOWN;这个也是压下的时候,区别在于只有不是第一根手指压下的时候才执行,
所以,我在压下的动作都初始化isFirstMoved=false;
当移动的时候,ACTION_MOVE也会执行。
由于移动的时候处理逻辑少的问题,出现屏幕越界后明显的白边反弹,因此在这里编辑了一部分代码。。。
滑动前,先判断能否滑动,滑动后,再次判断是否越界,因此,有效解决了白边反弹现象。
- /**
- *判断x方向上能不能滑动
- *@return可以滑动返回true
- */
- privatebooleancanSmoothX(){
- RectFrectf=getRectf(matrix);
- if(rectf.left>0||rectf.right<getwidth())
- returnfalse;
- returntrue;
- }
- /**
- *判断y方向上可不可以滑动
- *@return可以滑动返回true
- */
- privatebooleancanSmoothY(){
- RectFrectf=getRectf(matrix);
- if(rectf.top>0||rectf.bottom<getheight())
- returnfalse;
- returntrue;
- }
- /**
- *纠正出界的横和众线
- *@paramdx出界偏移的横线
- *@paramdy出街便宜的众线
- */
- privatevoidremedyXAndY(floatdx,floatdy){
- if(!canSmoothX())
- matrix.postTranslate(-dx,0);
- if(!canSmoothY())
- matrix.postTranslate(0,-dy);
- setImageMatrix(matrix);
- }
这段是用于滑动之后判断是否越界的,如果越界,把多余的dx和dy滑动回去。
完整的自定义控件代码:
- packagecom.test.gesturedemo.view;
- importandroid.content.Context;
- importandroid.graphics.Matrix;
- importandroid.graphics.RectF;
- importandroid.graphics.drawable.Drawable;
- importandroid.util.AttributeSet;
- importandroid.view.MotionEvent;
- importandroid.view.ScaleGestureDetector;
- importandroid.view.View;
- importandroid.view.ViewTreeObserver;
- importandroid.widget.ImageView;
- /**
- *Createdby13798on2016/6/3.
- */
- publicclassMyImageViewextendsImageViewimplementsScaleGestureDetector.OnScaleGestureListener,View.OnTouchListener{
- /**
- *控件宽度
- */
- privateintmWidth;
- /**
- *控件高度
- */
- privateintmHeight;
- /**
- *拿到src的图片
- */
- privateDrawablemDrawable;
- /**
- *图片宽度(使用前判断mDrawable是否null)
- */
- privateintmDrawableWidth;
- /**
- *图片高度(使用前判断mDrawable是否null)
- */
- privateintmDrawableHeight;
- /**
- *初始化缩放值
- */
- privatefloatmScale;
- /**
- *双击图片的缩放值
- */
- privatefloatmDoubleClickScale;
- /**
- *最大的缩放值
- */
- privatefloatmMaxScale;
- /**
- *最小的缩放值
- */
- privatefloatmMinScale;
- privateScaleGestureDetectorscaleGestureDetector;
- /**
- *当前有着缩放值、平移值的矩阵。
- */
- privateMatrixmatrix;
- publicMyImageView(Contextcontext){
- this(context,null);
- }
- publicMyImageView(Contextcontext,AttributeSetattrs){
- this(context,attrs,0);
- }
- publicMyImageView(Contextcontext,AttributeSetattrs,intdefStyleAttr){
- super(context,attrs,defStyleAttr);
- setOnTouchListener(this);
- scaleGestureDetector=newScaleGestureDetector(context,this);
- initListener();
- }
- /**
- *初始化事件监听
- */
- privatevoidinitListener(){
- //强制设置模式
- setScaleType(ScaleType.MATRIX);
- //添加观察者
- getViewTreeObserver().addOnGlobalLayoutListener(newViewTreeObserver.OnGlobalLayoutListener(){
- @Override
- publicvoidonGlobalLayout(){
- //移除观察者
- getViewTreeObserver().removeGlobalOnLayoutListener(this);
- //获取控件大小
- mWidth=getWidth();
- mHeight=getHeight();
- //通过getDrawable获得Src的图片
- mDrawable=getDrawable();
- if(mDrawable==null)
- return;
- mDrawableWidth=mDrawable.getIntrinsicWidth();
- mDrawableHeight=mDrawable.getIntrinsicHeight();
- initImageViewSize();
- moveToCenter();
- }
- });
- }
- /**
- *初始化资源图片宽高
- */
- privatevoidinitImageViewSize(){
- if(mDrawable==null)
- return;
- //缩放值
- floatscale=1.0f;
- //图片宽度大于控件宽度,图片高度小于控件高度
- if(mDrawableWidth>mWidth&&mDrawableHeight<mheight)
- scale=mWidth*1.0f/mDrawableWidth;
- //图片高度度大于控件宽高,图片宽度小于控件宽度
- elseif(mDrawableHeight>mHeight&&mDrawableWidth<mwidth)
- scale=mHeight*1.0f/mDrawableHeight;
- //图片宽度大于控件宽度,图片高度大于控件高度
- elseif(mDrawableHeight>mHeight&&mDrawableWidth>mWidth)
- scale=Math.min(mHeight*1.0f/mDrawableHeight,mWidth*1.0f/mDrawableWidth);
- //图片宽度小于控件宽度,图片高度小于控件高度
- elseif(mDrawableHeight<mheight&&mdrawablewidth<mwidth)
- scale=Math.min(mHeight*1.0f/mDrawableHeight,mWidth*1.0f/mDrawableWidth);
- mScale=scale;
- mMaxScale=mScale*8.0f;
- mMinScale=mScale*0.5f;
- }
- /**
- *移动控件中间位置
- */
- privatevoidmoveToCenter(){
- finalfloatdx=mWidth/2-mDrawableWidth/2;
- finalfloatdy=mHeight/2-mDrawableHeight/2;
- matrix=newMatrix();
- //平移至中心
- matrix.postTranslate(dx,dy);
- //以控件中心作为缩放
- matrix.postScale(mScale,mScale,mWidth/2,mHeight/2);
- setImageMatrix(matrix);
- }
- /**
- *@return当前缩放的值
- */
- privatefloatgetmScale(){
- float[]floats=newfloat[9];
- matrix.getValues(floats);
- returnfloats[Matrix.MSCALE_X];
- }
- /**
- *@parammatrix矩阵
- *@returnmatrix的ltbr和width,height
- */
- privateRectFgetRectf(Matrixmatrix){
- RectFf=newRectF();
- if(mDrawable==null)
- returnnull;
- f.set(0,0,mDrawableWidth,mDrawableHeight);
- matrix.mapRect(f);
- returnf;
- }
- @Override
- publicbooleanonScale(ScaleGestureDetectordetector){
- if(mDrawable==null){
- returntrue;
- }
- //系统定义的缩放值
- floatscaleFactor=detector.getScaleFactor();
- //获取已经缩放的值
- floatscale=getmScale();
- floatscaleResult=scale*scaleFactor;
- if(scaleResult>=mMaxScale&&scaleFactor>1.0f)
- scaleFactor=mMaxScale/scale;
- if(scaleResult<=mMinScale&&scaleFactor<1.0f)
- scaleFactor=mMinScale/scale;
- matrix.postScale(scaleFactor,scaleFactor,detector.getFocusX(),detector.getFocusY());
- RectFf=getRectf(matrix);
- floatdX=0.0f;
- floatdY=0.0f;
- //图片高度大于控件高度
- if(f.height()>=mHeight){
- //图片顶部出现空白
- if(f.top>0){
- //往上移动
- dY=-f.top;
- }
- //图片底部出现空白
- if(f.bottom<mheight){
- //往下移动
- dY=mHeight-f.bottom;
- }
- }
- //图片宽度大于控件宽度
- if(f.width()>=mWidth){
- //图片左边出现空白
- if(f.left>0){
- //往左边移动
- dX=-f.left;
- }
- //图片右边出现空白
- if(f.right<mwidth){
- //往右边移动
- dX=mWidth-f.right;
- }
- }
- if(f.width()<mwidth){
- dX=mWidth/2-f.right+f.width()/2;
- }
- if(f.height()<mheight){
- dY=mHeight/2-f.bottom+f.height()/2;
- }
- matrix.postTranslate(dX,dY);
- setImageMatrix(matrix);
- returntrue;
- }
- @Override
- publicbooleanonScaleBegin(ScaleGestureDetectordetector){
- returntrue;
- }
- @Override
- publicvoidonScaleEnd(ScaleGestureDetectordetector){
- floatscale=getmScale();
- if(scale<mscale){
- matrix.postScale(mScale/scale,mScale/scale,mWidth/2,mHeight/2);
- setImageMatrix(matrix);
- }
- }
- privatefloatdownX;
- privatefloatdownY;
- privatefloatnowMovingX;
- privatefloatnowMovingY;
- privatefloatlastMovedX;
- privatefloatlastMovedY;
- privatebooleanisFirstMoved=false;
- @Override
- publicbooleanonTouch(Viewv,MotionEventevent){
- switch(event.getAction()&MotionEvent.ACTION_MASK){
- caseMotionEvent.ACTION_DOWN:
- isFirstMoved=false;
- downX=event.getX();
- downY=event.getY();
- break;
- caseMotionEvent.ACTION_POINTER_DOWN:
- isFirstMoved=false;
- break;
- caseMotionEvent.ACTION_MOVE:
- nowMovingX=event.getX();
- nowMovingY=event.getY();
- if(!isFirstMoved){
- isFirstMoved=true;
- lastMovedX=nowMovingX;
- lastMovedY=nowMovingY;
- }
- floatdX=0.0f;
- floatdY=0.0f;
- RectFrectf=getRectf(matrix);
- //判断滑动方向
- finalfloatscrollX=nowMovingX-lastMovedX;
- //判断滑动方向
- finalfloatscrollY=nowMovingY-lastMovedY;
- //图片高度大于控件高度
- if(rectf.height()>mHeight&&canSmoothY()){
- dY=nowMovingY-lastMovedY;
- }
- //图片宽度大于控件宽度
- if(rectf.width()>mWidth&&canSmoothX()){
- dX=nowMovingX-lastMovedX;
- }
- matrix.postTranslate(dX,dY);
- remedyXAndY(dX,dY);
- lastMovedX=nowMovingX;
- lastMovedY=nowMovingY;
- break;
- caseMotionEvent.ACTION_UP:
- break;
- caseMotionEvent.ACTION_POINTER_UP:
- isFirstMoved=false;
- break;
- }
- returnscaleGestureDetector.onTouchEvent(event);
- }
- /**
- *判断x方向上能不能滑动
- *@return可以滑动返回true
- */
- privatebooleancanSmoothX(){
- RectFrectf=getRectf(matrix);
- if(rectf.left>0||rectf.right<getwidth())
- returnfalse;
- returntrue;
- }
- /**
- *判断y方向上可不可以滑动
- *@return可以滑动返回true
- */
- privatebooleancanSmoothY(){
- RectFrectf=getRectf(matrix);
- if(rectf.top>0||rectf.bottom<getheight())
- returnfalse;
- returntrue;
- }
- /**
- *纠正出界的横和众线
- *@paramdx出界偏移的横线
- *@paramdy出街便宜的众线
- */
- privatevoidremedyXAndY(floatdx,floatdy){
- if(!canSmoothX())
- matrix.postTranslate(-dx,0);
- if(!canSmoothY())
- matrix.postTranslate(0,-dy);
- setImageMatrix(matrix);
- }
- }
activity的xml
- <relativelayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <com.test.gesturedemo.view.myimageview
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scaleType="matrix"
- android:src="@mipmap/tt1"/>
Android实现 通过手势随意缩放、移动ImageView图片相关推荐
- Android 双击和手势的图片缩放
2019独角兽企业重金招聘Python工程师标准>>> 代码: package com.mooc.view; import android.content.Context; impo ...
- android 手势事件 重写,Android实现通过手势控制图片大小缩放的方法
本文实例讲述了Android实现通过手势控制图片大小缩放的方法.分享给大家供大家参考,具体如下: 该程序实现的是通过手势来缩放图片,从左向右挥动图片时图片被放大,从右向左挥动图片时图片被缩小,挥动速度 ...
- Android 手势检测实战 打造支持缩放平移的图片预览效果(下)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39480503,本文出自:[张鸿洋的博客] 上一篇已经带大家实现了自由的放大缩小图 ...
- android 手势放缩_手把手教你打造支持手势放大缩小的ImageView
写在前面 最近有了新的任务,学习的时间比以前少了不少,Java回炉的文估计是得缓缓了,不过每周一篇尽量保质保量.最近感觉我文写的有点不好,因为我写东西除非必要,不然概念性的东西我基本上都是一笔带过-- ...
- android 布局 缩小图片大小,三大布局的基本摆放属性总结,以及imageVIew图片摆放的缩放问题...
(一)三大布局 1.FrameLayout帧布局 Android中最简单的一种布局,默认都是放在帧布局的左上角,通过android:layout_gravity来决定子控件的位置 2.LinearLa ...
- android photoview 图片放大缩放功能 ImageView
转自:http://blog.csdn.net/aaawqqq/article/details/43128111 Android 图片浏览功能 图片放大缩小 使用 photoview 双击或双指缩放 ...
- Android ImageView图片代码实现按屏幕宽度等比例缩放
/*** 设置图片根据屏幕宽度进行等比例缩放* @param imageView*/public static void setImageMatchScreenWidth(ImageView imag ...
- Android ImageView图片显示点击背景切换
为什么80%的码农都做不了架构师?>>> 一.介绍 ImageView用来显示任意图像图片,可以自己定义显示尺寸,显示颜色等等. 二.XML属性 android:adjustV ...
- android手势密码源码,Android自定义UI手势密码改进版源码下载
在之前文章的铺垫下,再为大家分享一篇:Android手势密码,附源码下载,不要错过. 先看第一张图片的布局文件 activity_main.xml xmlns:tools="http://s ...
最新文章
- 《Java 8 实战》(二)—— Lambda
- 将特定像素点在图像上连接起来_(NeurIPS 2019) Gated CRF Loss-一种用于弱监督图像语义分割的新型损失函数...
- Hibernate组件(Component)映射
- openstack云主机无法绑定ip_智汇华云|OpenStack 虚拟机 GPU 性能优化
- 蓝牙BLE LINK LAYER剖析(二) -- PDU
- java二叉树生成器_JAVA实现二叉树生成
- java虚拟机和javaGC_Java虚拟机(三):GC算法和种类
- 2020年平均工资出炉!这个行业最高
- 什么是Redis的VM机制
- vSphere 7 With K8s系列09:部署wordpress示例
- UDP --01--基本开发设计
- 趣图:程序猿和运维狗的工作日常……
- python经纬度转换xy坐标公式_Python经纬度坐标转换为距离及角度的实现
- 多线程下载王者荣耀高清壁纸
- springboot优缺点
- 龙与地下城中的人物属性
- 配置树莓派中文环境 及解决 no write since last change
- mybatis-学习笔记-联系我获取md文档
- Retrofit+协程使用填坑和优化
- 2023春节祝福系列第一弹(下)(放飞祈福孔明灯,祝福大家身体健康)(附完整源代码及资源免费下载)