今天刚发了一篇关于ImageView的缩放和拖拽的博客,然后我想了下,将他自定义下,方便我们来复用这个imageView,效果我就不多说了,http://blog.csdn.net/xiaanming/article/details/8827257就是这个效果,我只是把他抽出来自定义了下,代码还是贴上吧,我也将demo上传一下,有疑问大家指出来,大家共同学习,共同进步,呵呵
package com.example.myimageview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Matrix; import android.graphics.PointF; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.FloatMath; import android.view.MotionEvent; import android.view.View; import android.widget.ImageView; public class MyImageView extends ImageView{ Matrix matrix = new Matrix(); Matrix savedMatrix = new Matrix(); /**位图对象*/ private Bitmap bitmap = null; /** 屏幕的分辨率*/ private DisplayMetrics dm; /** 最小缩放比例*/ float minScaleR = 1.0f; /** 最大缩放比例*/ static final float MAX_SCALE = 15f; /** 初始状态*/ static final int NONE = 0; /** 拖动*/ static final int DRAG = 1; /** 缩放*/ static final int ZOOM = 2; /** 当前模式*/ int mode = NONE; /** 存储float类型的x,y值,就是你点下的坐标的X和Y*/ PointF prev = new PointF(); PointF mid = new PointF(); float dist = 1f; public MyImageView(Context context) { super(context); setupView(); } public MyImageView(Context context, AttributeSet attrs) { super(context, attrs); setupView(); } public void setupView(){ Context context = getContext(); //获取屏幕分辨率,需要根据分辨率来使用图片居中 dm = context.getResources().getDisplayMetrics(); //根据MyImageView来获取bitmap对象 BitmapDrawable bd = (BitmapDrawable)this.getDrawable(); if(bd != null){ bitmap = bd.getBitmap(); } //设置ScaleType为ScaleType.MATRIX,这一步很重要 this.setScaleType(ScaleType.MATRIX); this.setImageBitmap(bitmap); //bitmap为空就不调用center函数 if(bitmap != null){ center(true, true); } this.setImageMatrix(matrix); this.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK) { // 主点按下 case MotionEvent.ACTION_DOWN: savedMatrix.set(matrix); prev.set(event.getX(), event.getY()); mode = DRAG; break; // 副点按下 case MotionEvent.ACTION_POINTER_DOWN: dist = spacing(event); // 如果连续两点距离大于10,则判定为多点模式 if (spacing(event) > 10f) { savedMatrix.set(matrix); midPoint(mid, event); mode = ZOOM; } break; case MotionEvent.ACTION_UP:{ break; } case MotionEvent.ACTION_POINTER_UP: mode = NONE; //savedMatrix.set(matrix); break; case MotionEvent.ACTION_MOVE: if (mode == DRAG) { matrix.set(savedMatrix); matrix.postTranslate(event.getX() - prev.x, event.getY() - prev.y); } else if (mode == ZOOM) { float newDist = spacing(event); if (newDist > 10f) { matrix.set(savedMatrix); float tScale = newDist / dist; matrix.postScale(tScale, tScale, mid.x, mid.y); } } break; } MyImageView.this.setImageMatrix(matrix); CheckView(); return true; } }); } /** * 横向、纵向居中 */ protected void center(boolean horizontal, boolean vertical) { Matrix m = new Matrix(); m.set(matrix); RectF rect = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight()); m.mapRect(rect); float height = rect.height(); float width = rect.width(); float deltaX = 0, deltaY = 0; if (vertical) { // 图片小于屏幕大小,则居中显示。大于屏幕,上方留空则往上移,下方留空则往下移 int screenHeight = dm.heightPixels; if (height < screenHeight) { deltaY = (screenHeight - height) / 2 - rect.top; } else if (rect.top > 0) { deltaY = -rect.top; } else if (rect.bottom < screenHeight) { deltaY = this.getHeight() - rect.bottom; } } if (horizontal) { int screenWidth = dm.widthPixels; if (width < screenWidth) { deltaX = (screenWidth - width) / 2 - rect.left; } else if (rect.left > 0) { deltaX = -rect.left; } else if (rect.right < screenWidth) { deltaX = screenWidth - rect.right; } } matrix.postTranslate(deltaX, deltaY); } /** * 限制最大最小缩放比例,自动居中 */ private void CheckView() { float p[] = new float[9]; matrix.getValues(p); if (mode == ZOOM) { if (p[0] < minScaleR) { //Log.d("", "当前缩放级别:"+p[0]+",最小缩放级别:"+minScaleR); matrix.setScale(minScaleR, minScaleR); } if (p[0] > MAX_SCALE) { //Log.d("", "当前缩放级别:"+p[0]+",最大缩放级别:"+MAX_SCALE); matrix.set(savedMatrix); } } center(true, true); } /** * 两点的距离 */ private float spacing(MotionEvent event) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return FloatMath.sqrt(x * x + y * y); } /** * 两点的中点 */ private void midPoint(PointF point, MotionEvent event) { float x = event.getX(0) + event.getX(1); float y = event.getY(0) + event.getY(1); point.set(x / 2, y / 2); } }
布局文件需要注意了,使用<com.example.myimageview.MyImageView></com.example.myimageview.MyImageView>标签,怕一些新手不知道,别怪我啰嗦
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.example.myimageview.MyImageView android:id="@+id/imageview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:src="@drawable/item" > </com.example.myimageview.MyImageView> </RelativeLayout>
新建一个MainActivity咯,
package com.example.myimageview; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MyImageView myImageView = (MyImageView)findViewById(R.id.imageview); myImageView.setImageDrawable(getResources().getDrawable(R.drawable.item1)); } }
相关推荐
在这个案例中,我们关注的是一个自定义的ImageView,它不仅支持单点缩放和回弹,还能进行拖拽操作,并且能够实现多点触控的缩放功能。这样的组件在创建交互式图片查看器或者画廊应用时非常有用。下面我们将详细讨论...
默认情况下,ImageView可以按比例缩放图片以适应视图大小,但并不支持用户交互式的缩放操作。 二、手势检测 为了实现图片的双指缩放,我们需要利用Android的GestureDetector和ScaleGestureDetector类。...
- 拖动与缩放:通过监听滑动手势实现图片的拖动和 pinch-to-zoom 功能。 - 圆角图片:通过绘制九宫格或使用Shader实现圆角效果。 - 长图片滚动:对于超长图片,可以实现滚动查看,避免拉伸变形。 - 图片质量控制...
在实际项目中,以上功能往往会被封装成一个自定义的ImageView子类,以方便复用和扩展。这样的自定义控件可能会包含复杂的逻辑,包括手势识别、动画处理等,需要对Android的UI系统有深入的理解。 总的来说,"android...
在Android开发中,实现多点触控功能,如图片的拖拽、缩放和旋转,是提高用户体验的关键技术之一。本文将深入探讨如何在Android应用中实现这些特性,特别是针对多张图片的操作。 首先,我们需要了解Android中的触摸...
3. **自定义ImageView**:可能在源码中,开发者对ImageView进行了扩展,添加了特殊功能,比如手势缩放、旋转、拖动等交互效果,或者实现了更高效的图片加载策略。 4. **图片占位符与错误图**:在图片加载过程中,...
此外,为了方便其他开发者复用和扩展这个自定义View,良好的代码结构和注释是必要的。可以将核心功能封装为方法,提供公共API供外部调用,同时提供示例代码和详细的使用说明。 总之,“Android自定义View-圆环布局...
在Android开发中,多点触控(Multi-Touch)技术是一项关键特性,它允许用户同时使用两个或更多手指与屏幕进行交互,如缩放、旋转和拖动等操作。本项目是一个关于Android多点触控的实战应用,通过实现图片的双指缩放...
5. **手势检测**:除了简单的拖动,可能还需要支持缩放、旋转等手势操作。这可以通过GestureDetector和ScaleGestureDetector等类来实现。 6. **自定义View**:为了实现这些高级功能,可能需要自定义一个ImageView...
例如,可能创建了一个绘制圆形或者复杂图形的自定义View,或者实现了一些交互效果,如拖动、缩放等。 自定义View的实践中,开发者可能会遇到一些问题,比如性能优化、测量和布局的处理、触控事件的传递等。对于性能...
一个自定义View通常继承自View或其子类,如TextView、ImageView等。通过重写`onDraw()`方法,我们可以自定义绘制逻辑,利用Canvas对象进行图形绘制。例如,可以绘制复杂的形状、文字、图像,甚至实现动态效果。 在`...
本示例“PhotoWallFallsDemo多点触控”正是一个专注于提升用户体验的项目,它实现了对ImageView的自定义控制,允许用户通过多点触控来对图片进行缩放和拖动操作。这一功能对于创建照片墙、画廊应用或者任何需要用户...
- **手势操作**:可能支持缩放、旋转、拖动等手势识别,使得用户能交互式地操作图片。 - **图片加载优化**:可能实现了图片的异步加载和缓存机制,提高用户体验。 - **动画效果**:比如淡入淡出、平移、旋转等,...
- 如果需要支持多指拖动或者缩放,需要处理`MotionEvent`的`ACTION_POINTER_DOWN`和`ACTION_POINTER_UP`事件,以及`getPointerCount()`和`getPointerId()`方法。 8. **内存管理**: - 当图片较大时,要考虑内存...
在“GalleryDemo”这个示例项目中,开发者可能创建了一个自定义的`Adapter`,它负责加载图片资源,并将其封装为`ImageView`实例。这些`ImageView`可能设置了合适的`ScaleType`,以便在用户进行放大操作时能够平滑地...
在实现编辑功能时,开发者可能将编辑界面封装为一个`Fragment`,方便管理和复用。 8. **数据持久化**: 如果应用支持保存和恢复编辑状态,可能涉及到了数据持久化技术,如SQLite数据库、SharedPreferences或文件存储...
例如,你可以设置ImageView的最大缩放比例为其原始大小的2倍,最小缩放比例为1(即不缩放)。当缩放比例超过这些限制时,不再允许进一步的缩放操作。 至于图片的移动,可以通过GestureDetector类中的onScroll()方法...
这通常需要自定义ImageView来实现。 - GIF支持:支持GIF动图展示,可能需要使用第三方库如Glide的GifDrawable或者Android的AnimationDrawable2。 5. 视频拖放: - 实现视频拖放功能,需要处理触摸事件,计算手指...