Android 点击图片放大展示 展示中可调节图片的缩放显示 图片查看器
2017-01-09 21:48
501 查看
1.首先需要初始化一个全局常量
这个是常量的工具类
初始化的方法就是在程序的Application类对的oncreat方法中执行
2.可缩放的ImageView
3.用于展示图片的Activity
此Activity的布局文件是:
4.主体都写完了,接下来就是调用了
博主是这样调用的。
后续,其实Bimp.bmp.add(bm);在这句代码里再添加的时候,可以实现左右滑动来展示图片,毕竟我们用的是ViewPager,但是博主在项目中展示的时候,需要实现微信的效果,还没有构思出符合项目已有代码的逻辑,得加油啦。。。
5.此篇文章,我其实结合了在网上查找的两个Demo。
说什么我都不能确定那两个Demo的源码地址了,太对不起作者了,我已免费资源的方式放到这两个网址中:
明天评论里补这两个Demo的地址,今天这资源我是传不上去了。
这个是常量的工具类
public final class GlobalConstant { private static int DEVICE_WIDTH; private static int DEVICE_HEIGHT; private static float DEVICE_DENSITY; public static void initDeviceInfo(Context context) { WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics metrics = new DisplayMetrics(); manager.getDefaultDisplay().getMetrics(metrics); DEVICE_WIDTH = metrics.widthPixels; DEVICE_HEIGHT = metrics.heightPixels; DEVICE_DENSITY = metrics.density; } public static int getDeviceWidth() { return DEVICE_WIDTH; } public static int getDeviceHeight() { return DEVICE_HEIGHT; } public static float getDeviceDensity() { return DEVICE_DENSITY; } }
初始化的方法就是在程序的Application类对的oncreat方法中执行
GlobalConstant.initDeviceInfo(this);
2.可缩放的ImageView
public class GestureImageView extends ImageView implements ViewTreeObserver.OnGlobalLayoutListener { private static final String TAG = GestureImageView.class.getSimpleName(); private boolean isOnce = true; //初始缩放值 private float currentScale; private static int mWidth = GlobalConstant.getDeviceWidth(); private static int mHeight = GlobalConstant.getDeviceHeight(); private static int mDistance = (int) Math.sqrt((Math.pow(mWidth, 2) + Math.pow(mHeight, 2))); private final float MAX_SCALE = 4.0f; // 修改这个值可以修改缩放最大值 private float MIN_SCALE; private float[] mMatrixValues = new float[9]; private float[] initMatrixValues = new float[9]; private Matrix mMatrix = new Matrix(); private PointF scalePointF; private PointF dragPointF; private float preDistance = 0; private static final int SCALE_RATE = 4;//修改此值用以修改缩放速率 public GestureImageView(Context context) { super(context); initImageAttribute(); } public GestureImageView(Context context, AttributeSet attrs) { super(context, attrs); initImageAttribute(); } public GestureImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initImageAttribute(); } /** * 初始化图像属性 */ private void initImageAttribute() { setScaleType(ScaleType.MATRIX); setFocusable(true);// 触摸事件开启此参数用以搞事情 catchTouchEvent(true); } /** * 是否捕获touch事件 * * @param flag true捕获touch事件,false不捕获 */ public void catchTouchEvent(boolean flag) { if (getParent() != null) { getParent().requestDisallowInterceptTouchEvent(flag); } } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); getViewTreeObserver().addOnGlobalLayoutListener(this); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { getViewTreeObserver().removeOnGlobalLayoutListener(this); } else { getViewTreeObserver().addOnGlobalLayoutListener(null); } } @Override public void setImageResource(int resId) { super.setImageResource(resId); adjustImageMatrix(); } @Override public void setImageBitmap(Bitmap bm) { super.setImageBitmap(bm); adjustImageMatrix(); } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: catchTouchEvent(true); scalePointF = null; preDistance = 0; dragPointF = null; break; case MotionEvent.ACTION_MOVE: if (event.getPointerCount() == 2) { //两点触摸事件处理 handleScaleEvent(event); } if (event.getPointerCount() == 1) { //处理移动事件 handleDragEvent(event); } break; case MotionEvent.ACTION_POINTER_UP: 11ee7 if (event.getPointerCount() != 1) { scalePointF = null; preDistance = 0; dragPointF = null; } break; case MotionEvent.ACTION_UP: dragPointF = null; break; default: break; } return true; } /** * 处理拖拽手势 * * @param event 触摸Event */ private void handleDragEvent(MotionEvent event) { scalePointF = null; if (dragPointF == null) { dragPointF = new PointF(event.getX(), event.getY()); } else { float x = event.getX(); float y = event.getY(); drag(x - dragPointF.x, y - dragPointF.y); dragPointF = new PointF(x, y); } } /** * 处理缩放手势 * * @param event 事件 */ private void handleScaleEvent(MotionEvent event) { dragPointF = null; float fX = event.getX(0); float fY = event.getY(0); float sX = event.getX(1); float sY = event.getY(1); float distance = (float) Math.sqrt((Math.pow(fX - sX, 2) + Math.pow(fY - sY, 2))); if (scalePointF == null) { scalePointF = new PointF((fX + sX) / 2.0f, (fY + sY) / 2.0f); preDistance = distance; } else { float scale = (distance - preDistance) / mDistance * SCALE_RATE;//修改这个值可以更改缩放速率 float judge = currentScale + scale; scale = judge > MAX_SCALE || judge < MIN_SCALE ? (judge > MAX_SCALE ? MAX_SCALE - currentScale : MIN_SCALE - currentScale) : scale; currentScale += scale; scale(currentScale / (currentScale - scale), scalePointF); } preDistance = distance; } /** * 根据图像矩形处理拖拽的X值 * * @param rect 图像矩形 * @param dragX 拖拽的X值 * @return 处理以后dragX值 */ private float handleDragX(RectF rect, float dragX) { if (rect.left < 0 || rect.right > mWidth) { // 放大时,如果内容宽度大于屏幕,左右边界不能出现黑边 if (rect.left + dragX > 0) { dragX = 0 - rect.left; } else if (rect.right + dragX < mWidth) { dragX = mWidth - rect.right; } } else { dragX = 0; } return dragX; } /** * 根据图像矩形处理拖拽的Y值 * * @param rect 图像矩形 * @param dragY 拖拽的Y值 * @return 处理以后dragY值 */ private float handleDragY(RectF rect, float dragY) { if (rect.top <= 0 && rect.bottom >= mHeight) { // 放大时,如果内容宽度大于屏幕,左右边界不能出现黑边 if (rect.top + dragY > 0) { dragY = 0 - rect.top; } else if (rect.bottom + dragY < mHeight) { dragY = mHeight - rect.bottom; } } else { dragY = 0; } return dragY; } /** * 拖拽imageView * * @param dragX X轴的移动距离 * @param dragY Y轴的移动距离 */ private void drag(float dragX, float dragY) { RectF rect = getImageRectF(); catchTouchEvent(canDrag(rect)); dragX = handleDragX(rect, dragX); dragY = handleDragY(rect, dragY); mMatrix.postTranslate(dragX, dragY); setImageMatrix(mMatrix); mMatrix.getValues(mMatrixValues); } /** * 根据ImageView当前位置判断是否可以拖拽 * * @param currentRect 当前的矩形 * @return true可以拖拽,false不可以 */ private boolean canDrag(RectF currentRect) { RectF preRect = getInitialRectF(); boolean canDrag; if (preRect.left > 0) { canDrag = !(currentRect.left >= 0 || currentRect.right <= mWidth || (currentRect.left > 0 && currentScale == MAX_SCALE)); } else { canDrag = !(currentRect.left == 0 || currentRect.right == mWidth); } return canDrag; } /** * 获取初始的图像矩形 * * @return */ private RectF getInitialRectF() { Matrix preMatrix1 = new Matrix(); preMatrix1.setValues(initMatrixValues); return getImageRectF(preMatrix1); } /** * 缩放时,处理边缘不过界 * * @param matrix 拷贝的矩阵 * @param scale 缩放比例 * @param f 缩放中心点 * @return 返回X坐标的点 */ private float handleScaleDragX(Matrix matrix, float scale, PointF f) { matrix.postScale(scale, scale, f.x, mHeight / 2.0f); RectF rect = getImageRectF(matrix); // 根据拷贝过后的矩阵计算得出的矩形 RectF preRect = getInitialRectF(); float x = f.x; if (preRect.left > 0) { // 图片初始矩形宽度小于屏幕宽度 x = rect.left > 0 || rect.right < mWidth ? mWidth / 2.0f : x; } else { x = rect.left > 0 ? 0 : (rect.right < mWidth ? mWidth : x); } return x; } /** * 按照缩放比例和点进行缩放 * * @param scale 缩放比例 * @param f 包含缩放中心点的PointF */ private void scale(float scale, PointF f) { LogUtil.showLog("缩放的比率:scale", scale+""); if (scale<=(float)1.00) { scale=(float) 1.00; } Matrix matrix = new Matrix(mMatrix); mMatrix.postScale(scale, scale, handleScaleDragX(matrix, scale, f), mHeight / 2.0f); mMatrix.getValues(mMatrixValues); // getImageRectF(); if (currentScale == MIN_SCALE) {// 缩放到初始位置,将图片设置为初始位置,此处可以添加动画,请随意发挥。 mMatrix.setValues(initMatrixValues); setImageMatrix(mMatrix); } Log.i(TAG, "currentScale = " + currentScale); setImageMatrix(mMatrix); } /** * 将图像调整到适合的位置 */ private void adjustImageMatrix() { Drawable d = getDrawable(); if (d == null) { setImageResource(R.drawable.ic_launcher); return; } int width = d.getIntrinsicWidth(); int height = d.getIntrinsicHeight(); float scale = 1.0f; // 有3种情况,1、宽大于屏幕宽。2、高大于屏幕高。3、宽和高均大于屏幕,图像宽高均小于设备的暂时不考虑 if (width > mWidth && height < mHeight) { scale = mWidth * 1.0f / width; } if (height > mHeight && width < mWidth) { scale = mHeight * 1.0f / height; } if (height > mHeight && width > mWidth) { scale = Math.min(mWidth * 1.0f / width, mHeight * 1.0f / height); } currentScale = scale; MIN_SCALE = scale; mMatrix = new Matrix(); mMatrix.postTranslate((mWidth - width) / 2.0f, (mHeight - height) / 2.0f); mMatrix.postScale(currentScale, currentScale, mWidth / 2.0f, mHeight / 2.0f); mMatrix.getValues(mMatrixValues); mMatrix.getValues(initMatrixValues); setImageMatrix(mMatrix); getImageRectF(); } /** * 返回Drawable的矩形 * * @param matrix 拷贝出来的矩阵 * @return imageView矩形数据 */ private RectF getImageRectF(Matrix matrix) { RectF rect = new RectF(); Drawable d = getDrawable(); if (d != null) { rect.set(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); matrix.mapRect(rect); } return rect; } /** * 返回Drawable的矩形 * * @return imageView矩形数据 */ private RectF getImageRectF() { RectF rect = new RectF(); Drawable d = getDrawable(); if (d != null) { rect.set(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); mMatrix.mapRect(rect); } return rect; } @Override public void onGlobalLayout() { if (isOnce) { isOnce = false; adjustImageMatrix(); } } }
3.用于展示图片的Activity
import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.os.Bundle; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.view.View; import android.view.ViewGroup.LayoutParams; public class PhotoActivity extends Activity { private ArrayList<GestureImageView> listViews = null; private ViewPager pager; private MyPageAdapter adapter; public List<Bitmap> bmp = new ArrayList<Bitmap>(); public int max; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_photo); for (int i = 0; i < Bimp.bmp.size(); i++) { bmp.add(Bimp.bmp.get(i)); } max = Bimp.max; pager = (ViewPager) findViewById(R.id.viewpager); pager.setOnPageChangeListener(pageChangeListener); pager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); for (int i = 0; i < bmp.size(); i++) { initListViews(bmp.get(i)); } adapter = new MyPageAdapter(listViews);// 构造adapter pager.setAdapter(adapter);// 设置适配器 Intent intent = getIntent(); int id = intent.getIntExtra("ID", 0); pager.setCurrentItem(id); } @SuppressWarnings("deprecation") private void initListViews(Bitmap bm) { if (listViews == null) listViews = new ArrayList<GestureImageView>(); GestureImageView img = new GestureImageView(this);// 构造textView对象 img.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); img.setBackgroundColor(0xff000000); img.setImageBitmap(bm); img.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT)); listViews.add(img);// 添加view } private OnPageChangeListener pageChangeListener = new OnPageChangeListener() { public void onPageSelected(int arg0) {// 页面选择响应函数 } public void onPageScrolled(int arg0, float arg1, int arg2) {// 滑动中。。。 } public void onPageScrollStateChanged(int arg0) {// 滑动状态改变 } }; class MyPageAdapter extends PagerAdapter { private ArrayList<GestureImageView> listViews;// content private int size;// 页数 public MyPageAdapter(ArrayList<GestureImageView> listViews) {// 构造函数 // 初始化viewpager的时候给的一个页面 this.listViews = listViews; size = listViews == null ? 0 : listViews.size(); } public void setListViews(ArrayList<GestureImageView> listViews) {// 自己写的一个方法用来添加数据 this.listViews = listViews; size = listViews == null ? 0 : listViews.size(); } public int getCount() {// 返回数量 return size; } public int getItemPosition(Object object) { return POSITION_NONE; } public void destroyItem(View arg0, int arg1, Object arg2) {// 销毁view对象 ((ViewPager) arg0).removeView(listViews.get(arg1 % size)); } public void finishUpdate(View arg0) { } public Object instantiateItem(View arg0, int arg1) {// 返回view对象 try { ((ViewPager) arg0).addView(listViews.get(arg1 % size), 0); } catch (Exception e) { LogUtil.showLogerror("执行instantiateItem方法时报错:", e.toString()); } return listViews.get(arg1 % size); } public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } } }
此Activity的布局文件是:
<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" android:orientation="vertical" > <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" > </android.support.v4.view.ViewPager> </RelativeLayout>
4.主体都写完了,接下来就是调用了
博主是这样调用的。
Bitmap bm = Bimp.revitionImageSize(path); //图片的本地路径 Bimp.bmp.add(bm); Intent intent = new Intent(ctx,PhotoActivity.class); intent.putExtra("ID", 0); ctx.startActivity(intent);
后续,其实Bimp.bmp.add(bm);在这句代码里再添加的时候,可以实现左右滑动来展示图片,毕竟我们用的是ViewPager,但是博主在项目中展示的时候,需要实现微信的效果,还没有构思出符合项目已有代码的逻辑,得加油啦。。。
5.此篇文章,我其实结合了在网上查找的两个Demo。
说什么我都不能确定那两个Demo的源码地址了,太对不起作者了,我已免费资源的方式放到这两个网址中:
明天评论里补这两个Demo的地址,今天这资源我是传不上去了。
相关文章推荐
- 实现xlistview+xutils展示数据之后点击item跳转页面显示图片缩放和放大
- Android 在ViewPager中使用的可以画线,放大,保存,点击删除线条的自定义图片显示控件
- android利用抽屉添加图片,点击图片可以放大显示
- ANDROID展示HTML图文混排--实现图片缩小并点击放大
- Android TextView 显示网络图片,点击放大
- Android中下载图片展示到界面点击放大
- Android中Textview显示Html,图文混排,支持图片点击放大
- Android中Textview显示Html,图文混排,支持图片点击放大
- Android中下载图片展示到界面点击放大
- 多图展示点击切换效果模拟的flash效果,点小图放大显示,再点恢复默认。
- android 图片放大缩小 多点缩放
- Android放大缩小显示图片
- 所有图片自动缩放并点击放大
- [转载]Android开发之--读取文件夹下图片生成略缩图并点击显示大图
- android ImageView 视屏幕情况 使图片在限定范围内进行缩放显示
- Android中图片的展示之Webview居中显示图片
- android点击实现图片放大缩小 - java技术博客
- android点击实现图片放大缩小
- 多图展示点击切换效果模拟的flash效果,点小图放大显示,再点恢复默认。
- 项目总结(图片缩小,点击上移下移,点击弹出图片放大显示)