(Android学习笔记四)立体Gallery和多点触控浏览图片
来源:互联网 发布:如何删除数据执行保护 编辑:程序博客网 时间:2024/04/29 12:26
今天才刚考完试,终于有时间整理下之前写的一个小程序了,代码放在三维Gallery这里,有兴趣的可以下载。
实现效果如图,从系统的MediaStore数据库读取图片,组成稍带立体感的Gallery。点击图片跳到另一个页面浏览,可以用一根手指拖动或者两根手指一起来放大缩小。
程序包含5个JAVA文件。
1 ThreeDimensionalGalleryActivity是主Activity,主界面main.xml只有一个元素---自写的GalleryFlow。这类遍历MediaStore数据库读取图片的URI,将URI数组传给ImageAdapter处理照片,同时设置ImageAdapter为GalleryFlow的适配器。添加图片的单击响应事件,单击图片将跳转至ImageDetailActivity。
2 ImageAdapter继承自BaseAdapter,实现了常见的getView、getCount等接口。根据传进来的URI数组,读取图片并用Matrix倒转图像,用Canvas和Paint重新画出一个完整的Bitmap(包含原图、有阴影效果的倒影图像)。
3 GalleryFlow继承自Gallery类,重写了getChildStaticTransformation方法,使得传统Gallery两边的图片稍微旋转倾斜,中间不变,产生立体效果。
4 MultiPointTouchListener实现了OnTouchListener的接口,修改了onTouch方法,重新解析手指的触屏操作(平移、特别是缩放利用到多点触摸),并根据操作用Matrix处理传进来的ImageView。
5 ImageDetailActivity仅展示用户点击的那张图片,设置OnTouchListener为MultiPointTouchListener。
部分代码:
public class MultiPointTouchListener implements OnTouchListener { // 利用Matrix来移动和缩放图片 Matrix matrix = new Matrix(); Matrix savedMatrix = new Matrix(); // 三种状态 static final int NONE = 0; static final int DRAG = 1; static final int ZOOM = 2; int mode = NONE; // 缩放用到的点,记录下来 PointF start = new PointF(); PointF mid = new PointF(); float oldDist = 1f; @Override public boolean onTouch(View v, MotionEvent event) { ImageView view = (ImageView) v; // 这里处理触屏事件 switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN://第一根手指按下 matrix.set(view.getImageMatrix()); savedMatrix.set(matrix); start.set(event.getX(), event.getY()); mode = DRAG; break; case MotionEvent.ACTION_POINTER_DOWN://第二根手指按下 oldDist = spacing(event); if (oldDist > 10f) { savedMatrix.set(matrix); midPoint(mid, event); mode = ZOOM; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: mode = NONE; break; case MotionEvent.ACTION_MOVE: if (mode == DRAG) { matrix.set(savedMatrix); //M' = T(dx, dy) * M,平移操作 matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); } else if (mode == ZOOM) { float newDist = spacing(event); if (newDist > 10f) { matrix.set(savedMatrix); float scale = newDist / oldDist; matrix.postScale(scale, scale, mid.x, mid.y); } } break; } view.setImageMatrix(matrix); return 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); }}读取MediaStore数据库,读到的URI写进数组。
public boolean getPhotoURIs() { Uri uri=null; String projection[]={MediaStore.Images.Media._ID}; try{ ContentResolver cr=this.getContentResolver(); Cursor cursor = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,projection, null, null, null); if(null==cursor) return false; if(cursor.getCount()==0){ cursor.close(); return false; } uriArray=new Uri[cursor.getCount()]; int i=0; while(cursor.moveToNext()&&i<cursor.getCount()){ cursor.moveToPosition(i); uri=Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID))+""); uriArray[i]=uri; i++; } cursor.close(); } catch(Exception ex){ ex.printStackTrace(); } return true; }ImageAdapter里读取Bitmap,创建新位图:
public boolean createReflectedImages() { final int reflectionGap = 4;//倒影图和原图之间的距离 int index = 0; for (Uri uri : mURIs) {try {BitmapFactory.Options bitmapOptions = new BitmapFactory.Options(); bitmapOptions.inSampleSize = 4;Bitmap originalImage = BitmapFactory.decodeStream(mContext.getContentResolver().openInputStream(uri),null,bitmapOptions);if(originalImage==null)continue;int width = originalImage.getWidth(); int height = originalImage.getHeight(); if(height<=0||width<=0) continue; //利用Matrix来创建倒影图,倒影高度为原图1/2 Matrix matrix = new Matrix(); matrix.preScale(1, -1); Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, height/2, width, height/2, matrix, false); //创建一个宽度不变,高度为原图+倒影图高度的位图 Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height / 2), Config.ARGB_8888); //将上面创建的位图初始化到画布 Canvas canvas = new Canvas(bitmapWithReflection); canvas.drawBitmap(originalImage, 0, 0, null); Paint deafaultPaint = new Paint(); deafaultPaint.setAntiAlias(false); canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null); Paint paint = new Paint(); paint.setAntiAlias(false); //给倒影设置阴影 LinearGradient shader = new LinearGradient(0,originalImage.getHeight(), 0, bitmapWithReflection.getHeight() + reflectionGap,0x70ffffff, 0x00ffffff, TileMode.MIRROR); paint.setShader(shader); paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.DST_IN)); //用已经定义好的画笔构建一个矩形阴影渐变效果 canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()+ reflectionGap, paint); //创建一个ImageView用来显示已经画好的bitmapWithReflection ImageView imageView = new ImageView(mContext); imageView.setImageBitmap(bitmapWithReflection); //设置imageView大小 ,不能太大 imageView.setLayoutParams(new GalleryFlow.LayoutParams(300, 400)); mImages[index++] = imageView;//有占用内存过多的风险!} catch (FileNotFoundException e) {e.printStackTrace();} } return true; }
- (Android学习笔记四)立体Gallery和多点触控浏览图片
- android学习笔记37--------------多点触控缩放图片及单点触控图片移动
- Android-使用Gallery制作图片浏览册
- Gallery图片浏览
- Android学习笔记_38_图片的拖动、缩放功能和多点触摸
- Android-- Gallery学习笔记
- Android ImageSwitcher 和 Gallery 浏览图片时 OutofMemory问题的解决
- ANDROID图片浏览(带水平滑动的GridView和类似gallery的ViewPage)
- Android自定义控件ImageViwe(四)——多点触控实现图片的自由移动
- Android页面左右滑动浏览图片(Gallery示例)
- android 用ImageSwitcher+Gallery实现图片浏览效果
- Android UI, Gallery(过时), ImageSwitcher, 简单图片浏览工具
- android Gallery 3D 倒影图片浏览 解决oom问题
- 使用ImageSwitcher和Gallery实现图片的浏览
- 使用ImageSwitcher和Gallery实现图片的浏览
- GridView和Gallery两个控件实现图片浏览
- Gallery+ImageView实现图片浏览
- Gallery实现缩略图图片浏览
- Android 15本经典教程和150多个实例源码
- 项目开发全过程跟踪二
- HDFS之NameNode分析
- 母函数
- 《那些年啊,那些事——一个程序员的奋斗史》——64
- (Android学习笔记四)立体Gallery和多点触控浏览图片
- c#对于如何释放资源的解释
- 外观模式
- 读书笔记之《C语言编程技巧程序集》
- oracle常用分析函数
- [作业]最长上升子序列
- 提速Windows 7宽带上网速度
- Emacs 新闻组 之四 联系人管理
- 关掉Windows 7 窗口自动最大化功能