可移动的ImageView
来源:互联网 发布:库里2016-2017赛季数据 编辑:程序博客网 时间:2024/04/30 12:35
今天做了一个可移动的ImageView,要点如下:
1 ontouch
2 ongloballayout
3 image放置适当的位置
4 matrix变换(平移,缩放)
代码很简单
activity_main.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" tools:context=".MainActivity"> <com.none.view.MoveImage android:id="@+id/id_img" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="matrix" /></RelativeLayout>MainActivity.java
package com.none.moveimage;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.widget.ImageView;import com.none.view.MoveImage;public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MoveImage img = (MoveImage)findViewById(R.id.id_img); img.setImageResource(R.drawable.dou); }}MoveImage.java
package com.none.view;import android.content.Context;import android.graphics.Matrix;import android.graphics.RectF;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;import android.view.ViewTreeObserver;import android.widget.ImageView;/** * Created by pc on 2015/5/11. */public class MoveImage extends ImageView implements ViewTreeObserver.OnGlobalLayoutListener, View.OnTouchListener { private boolean mInit; private boolean mIsCanMove; private float mLastX; private float mLastY; private Matrix mScaleMatrix; private int mMoveSlop; public MoveImage(Context context) { this(context, null); } public MoveImage(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MoveImage(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private void init(Context context) { mScaleMatrix = new Matrix(); mMoveSlop = ViewConfiguration.get(context).getScaledTouchSlop(); setOnTouchListener(this); mIsCanMove = false; } @Override protected void onAttachedToWindow() { getViewTreeObserver().addOnGlobalLayoutListener(this); } @Override protected void onDetachedFromWindow() { getViewTreeObserver().removeOnGlobalLayoutListener(this); } @Override public void onGlobalLayout() { if (!mInit) { Drawable d = getDrawable(); if (d != null) { float scale = 1.0f; int dw = d.getIntrinsicWidth(); int dh = d.getIntrinsicHeight(); int width = getWidth(); int height = getHeight(); if (dw > width && dh < height) { scale = width * 1.0f / dw; } else if (dw < width && dh > height) { scale = height * 1.0f / dh; } else if (dw < width && dh < height) { scale = Math.min(width * 1.0f / dw, height * 1.0f / dh); } else if (dw > width && dh > height) { scale = Math.min(width * 1.0f / dw, height * 1.0f / dh); } else { scale = 1.0f; } int centerX = (width - dw) / 2; int centerY = (height - dh) / 2; mScaleMatrix.postTranslate(centerX, centerY); scale = scale / 2.0f; mScaleMatrix.postScale(scale, scale, width / 2, height / 2); setImageMatrix(mScaleMatrix); } } mInit = true; } private RectF getMatrixRectF() { RectF rectf = new RectF(); final Matrix matrix = mScaleMatrix; Drawable d = getDrawable(); if (d != null) { rectf.set(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); matrix.mapRect(rectf); } return rectf; } private boolean isMoveAction(float dx, float dy) { return Math.sqrt(dx * dx + dy * dy) > mMoveSlop; } @Override public boolean onTouch(View v, MotionEvent event) { RectF rectF = getMatrixRectF(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mLastX = event.getX(); mLastY = event.getY(); mIsCanMove = rectF.contains(mLastX, mLastY); break; case MotionEvent.ACTION_MOVE: if (mIsCanMove) { float x = event.getX(); float y = event.getY(); float deltaX = x - mLastX; float deltaY = y - mLastY; if (isMoveAction(deltaX, deltaY)) { checkBorderWhenMove(deltaX, deltaY, rectF); setImageMatrix(mScaleMatrix); } mLastX = x; mLastY = y; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: mIsCanMove = false; break; } return true; } private void checkBorderWhenMove(float deltaX, float deltaY, RectF rectF) { int width = getWidth(); int height = getHeight(); if (rectF.left + deltaX < 0) { deltaX = -rectF.left; } else if (rectF.right + deltaX > width) { deltaX = width - rectF.right; } if (rectF.top + deltaY < 0) { deltaY = -rectF.top; } else if (rectF.bottom + deltaY > height) { deltaY = height - rectF.bottom; } mScaleMatrix.postTranslate(deltaX, deltaY); }}
其中图片缩放使用了matrix方式,在xml中需要将imageview的scale方式设置为matrix。
之后在根据ongloballayout中的得到的图片size和屏幕大小进行比例计算,之后使用matrix.postscale对图片进行缩放。
图片的平移使用了matrix.posttranslate,平移的距离可随意指定。
另外还需要获得每次缩放后图片的rectf,也就是图片当前的位置。这个可以使用matrix.maprect获得。
最后在ontouch中控制图片的平移,在Down中对触摸点进行判断,非图片的点击不会对图片产生影响,当点击的是图片时,使用setimagematrix对图片移动进行刷新。
在移动的过程中判断图片是否会移动出屏幕,对上下左右进行判断,防止图片移动出屏幕。
参考http://www.imooc.com/learn/239中对图片伸缩和伸缩和的上下左右位置的处理。
0 0
- 可移动的ImageView
- 【Android】可移动的ImageView
- Android:手把手教你打造可缩放移动的ImageView
- 可缩放的ImageView
- ViewPager滑动后,可移动的Imageview会回到初始化的位置
- android自定义view实现可自由放大缩小和移动的imageView
- Android:手把手教你打造可缩放移动的ImageView(上)
- Android:手把手教你打造可缩放移动的ImageView(下)
- Android:手把手教你打造可缩放移动的ImageView(上)
- Android可拖动的ImageView
- 点击可变暗的ImageView
- 可放大缩小的ImageView
- 放大可以移动的ImageView
- 可移动的模块
- 可移动的菜单栏
- 可移动的div
- 可移动的CollectionViewCell
- Android 可平移,缩放,旋转的ImageView
- linux(3)命令——pwd命令
- shell 系统时间
- 六国论
- umeng分享 已安装QQ,但总提示“没有安装手机QQ客户端”
- Clone Graph BFS
- 可移动的ImageView
- anroid cookie
- Linux vsftp
- Android 中 ScrollView滚动不到最底端的解决方法
- UIALertView的基本用法与UIAlertViewDelegate对对话框的事件处理方法
- Hue(三)集成Hadoop
- 发送短信验证码(天翼开放平台)
- Gas Station 汽车加油问题
- ObjC的initialize和init