
我们知道,进入百度图片后,输入一个关键字后,首先看到的是很多缩略图,当我们点击某张缩略图时,我们就可以进入到大图显示页面,在大图显示页面,中包含了一个图片画廊,同时当前大图为刚刚我们点击的那张图片。现在我们看看在AndroID中如何实现类似的效果:
首先,我们需要有一个控件来显示缩略图,这里没有什么比GrIDVIEw更加合适了。
配置文件如下:
<?xml version="1.0" enCoding="utf-8"?> <linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:orIEntation="vertical" androID:layout_wIDth="fill_parent" androID:layout_height="fill_parent" > <GrIDVIEw androID:ID="@+ID/vIEw_photos" androID:layout_wIDth="fill_parent" androID:layout_height="fill_parent" androID:layout_margintop="10dp" androID:columnWIDth="100dp" androID:numColumns="auto_fit" androID:horizontalSpacing="5dp" androID:verticalSpacing="5dp" androID:ListSelector="@drawable/frame_select" /> </linearLayout>
对于GrIDVIEw中每一项是一张缩略图,我们需要继承BaseAdapter,实现自己的一个GrIDImageAdapter,代码:
package com.liner.manager; import java.util.List; import com.liner.manager.adapter.GrIDImageAdapter; import androID.app.Activity; import androID.graphics.Bitmap; import androID.os.Bundle; import androID.vIEw.VIEw; import androID.Widget.AdapterVIEw; import androID.Widget.gallery; import androID.Widget.Imagebutton; import androID.Widget.AdapterVIEw.OnItemClickListener; public class galleryActivity extends Activity{ private Imagebutton currentimage; private gallery gallery; private int[] thumbIDs; private int currentPos; private Bitmap currentBitmap; private List<Bitmap> bitmapCache; public voID onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentVIEw(R.layout.gallery); currentimage = (Imagebutton)this.findVIEwByID(R.ID.image_current); gallery = (gallery)this.findVIEwByID(R.ID.image_gallery); gallery.setonItemClickListener(galleryItemClickListener); init(); } private OnItemClickListener galleryItemClickListener = new OnItemClickListener() { @OverrIDe public voID onItemClick(AdapterVIEw<?> p,VIEw v,int position,long ID) { // 点击事件 showCurrentimage(position); } }; private voID init(){ thumbIDs = this.getIntent().getIntArrayExtra("thumbIDs"); currentPos = this.getIntent().getIntExtra("currentPos",0); //galleryIDs = this.getthumbnailIDs(currentPos); //当前的gallery里的图片信息 bitmapCache = BitmapUtils.querythumbnailListByIDs(this,thumbIDs); GrIDImageAdapter adapter = new GrIDImageAdapter(this.getApplication(),bitmapCache); gallery.setAdapter(adapter); gallery.setSelection(currentPos); showCurrentimage(currentPos); } private voID showCurrentimage(int position){ if(currentBitmap != null){ currentBitmap.recycle(); } currentBitmap = BitmapUtils.queryImageBythumbnailID(galleryActivity.this,thumbIDs[position]); if(currentBitmap != null){ currentimage.setimageBitmap(currentBitmap); }else{ //什么都不做 } //releaseBitmaps(); } /** * 将gallery当前可见的显示之前的3张,后3张缓存起来,其余的释放掉,这样是为了放置内存不够用 * 之所以前三张后三张,是为了gallery可以滑动的更加顺畅 */ private voID releaseBitmaps(){ int start = gallery.getFirstVisibleposition()-3; //缓存的起始位置 int end = gallery.getLastVisibleposition()+3; //缓存的结束位置 Bitmap delBitmap; for(int i=0; i<start; i++){ delBitmap = bitmapCache.get(i); if(delBitmap != null){ bitmapCache.remove(i); delBitmap.recycle(); } } for(int i=end+1; i<bitmapCache.size(); i++){ delBitmap = bitmapCache.get(i); if(delBitmap != null){ bitmapCache.remove(i); delBitmap.recycle(); } } } /** * 获取当前位置的前三个ID和后三个ID * @param position * @return */ private Integer[] getthumbnailIDs(int position){ Integer[] IDs = new Integer[]{0,0}; int currPos = 0; //关于这里的处理,比较复杂 for(int i=3; i>0; i--){ if(position - i >= 0){ currPos = 3-i; IDs[currPos] = thumbIDs[position-i]; } } IDs[++currPos] = thumbIDs[position]; //当前ID //currgallerySelection = currPos; //这样右边剩下的位置数就是7-currPos-1 for(int i=1; i<=6-currPos;i++){ if(position+i < thumbIDs.length){ IDs[currPos+i] = thumbIDs[position+i]; } } return IDs; } } 然后,我们就可以在Activity中通过查询MediaStore的多媒体图片库来查询所有的图片的缩略图,缩略图所在的位置是:
MediaStore.Images.thumbnails。Activity代码如下:
package com.liner.manager; import java.util.ArrayList; import java.util.List; import com.liner.manager.adapter.GrIDImageAdapter; import androID.app.Activity; import androID.content.Intent; import androID.database.Cursor; import androID.graphics.Bitmap; import androID.graphics.BitmapFactory; import androID.net.Uri; import androID.os.Bundle; import androID.provIDer.MediaStore; import androID.vIEw.VIEw; import androID.Widget.Adapter; import androID.Widget.AdapterVIEw; import androID.Widget.GrIDVIEw; import androID.Widget.Toast; public class MainActivity extends Activity { private GrIDVIEw photoVIEw; private GrIDImageAdapter imageAdapter; private Cursor cursor; private int[] thumbIDs; @OverrIDe public voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.main); photoVIEw = (GrIDVIEw)this.findVIEwByID(R.ID.vIEw_photos); photoVIEw.setonItemClickListener(photoClickListener); //showImages(); showthumbnails(); } private voID showthumbnails(){ cursor = BitmapUtils.querythumbnails(this); if(cursor.movetoFirst()){ List<Bitmap> bitmaps = new ArrayList<Bitmap>(); thumbIDs = new int[cursor.getCount()]; for(int i=0; i<cursor.getCount();i++){ cursor.movetoposition(i); String currPath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.thumbnails.DATA)); thumbIDs[i] = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Images.thumbnails._ID)); Bitmap b = BitmapUtils.decodeBitmap(currPath,100,100); bitmaps.add(b); } imageAdapter = new GrIDImageAdapter(this.getApplication(),bitmaps); photoVIEw.setAdapter(imageAdapter); } } private AdapterVIEw.OnItemClickListener photoClickListener = new AdapterVIEw.OnItemClickListener() { @OverrIDe public voID onItemClick(AdapterVIEw<?> p,long ID) { //点击某张缩略图时,转到图片显示界面 Intent intent = new Intent(); intent.setClass(MainActivity.this,galleryActivity.class); intent.putExtra("thumbIDs",thumbIDs); intent.putExtra("currentPos",position); startActivity(intent); } }; } 注意到,我们记录了,所有缩略图对应的ID号,和当前的用户选择的位置,然后通过Intent传递到第二个展示界面。第二个界面的布局文件如下:我们用了一个gallery和一个Imagebutton来实现
<?xml version="1.0" enCoding="utf-8"?> <linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="fill_parent" androID:layout_height="fill_parent" androID:orIEntation="vertical"> <gallery androID:ID="@+ID/image_gallery" androID:layout_wIDth="fill_parent" androID:layout_height="100dp" /> <Imagebutton androID:ID="@+ID/image_current" androID:layout_wIDth="fill_parent" androID:layout_height="fill_parent" androID:padding="10dp" androID:layout_margintop="10dp" /> </linearLayout>
然后,对应的Activity如下:
package com.liner.manager; import java.util.List; import com.liner.manager.adapter.GrIDImageAdapter; import androID.app.Activity; import androID.graphics.Bitmap; import androID.os.Bundle; import androID.vIEw.VIEw; import androID.Widget.AdapterVIEw; import androID.Widget.gallery; import androID.Widget.Imagebutton; import androID.Widget.AdapterVIEw.OnItemClickListener; public class galleryActivity extends Activity{ private Imagebutton currentimage; private gallery gallery; private int[] thumbIDs; private int currentPos; private Bitmap currentBitmap; private List<Bitmap> bitmapCache; public voID onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentVIEw(R.layout.gallery); currentimage = (Imagebutton)this.findVIEwByID(R.ID.image_current); gallery = (gallery)this.findVIEwByID(R.ID.image_gallery); gallery.setonItemClickListener(galleryItemClickListener); init(); } private OnItemClickListener galleryItemClickListener = new OnItemClickListener() { @OverrIDe public voID onItemClick(AdapterVIEw<?> p,thumbIDs[position]); if(currentBitmap != null){ currentimage.setimageBitmap(currentBitmap); }else{ //什么都不做 } //releaseBitmaps(); } } 可以看到,当用户点击gallery中某一项时,触发onItemClick事件,在其中,我们通过根据该缩略图对应的Image_ID来从MediaStore.Images.Media中查询该缩略图对应的大图。并在Imagebutton中显示。
这里当图片很多时,可能会出现内存溢出,为了避免这种情况,可以更加gallery的特点,使用缓存。保存当前可见的缩略图的前三个到后三个。其余的全部recycle。当用户点击gallery的时候,在判断当前的位置,如果大于或小于某个值时,则重新更新缓存。这样保证内存中的缩略图的个数总是6+gallery.getLastVisibleposition-gallery.getFirstVisibleposition个。其实这就是浮动缓存窗口,一个固定大小窗口在整个坐标(全部缩略图)上游动。这里没有实现,以后待续。
同时,你可能已经注意到,程序中使用到了一个BitmapUtils类,这个类是封装了一系列对查询图片,并将其解析为Bitmap的类。
代码如下:
package com.liner.manager; import java.util.ArrayList; import java.util.List; import androID.app.Activity; import androID.database.Cursor; import androID.graphics.Bitmap; import androID.graphics.BitmapFactory; import androID.provIDer.MediaStore; import androID.util.Log; public final class BitmapUtils { public static Bitmap decodeBitmap(String path,int displayWIDth,int displayHeight){ BitmapFactory.Options op = new BitmapFactory.Options(); op.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodefile(path,op); //获取尺寸信息 //获取比例大小 int wRatio = (int)Math.ceil(op.outWIDth/(float)displayWIDth); int hRatio = (int)Math.ceil(op.outHeight/(float)displayHeight); //如果超出指定大小,则缩小相应的比例 if(wRatio > 1 && hRatio > 1){ if(wRatio > hRatio){ op.inSampleSize = wRatio; }else{ op.inSampleSize = hRatio; } } op.inJustDecodeBounds = false; bmp = BitmapFactory.decodefile(path,op); return Bitmap.createScaledBitmap(bmp,displayWIDth,displayHeight,true); } /** * 采用复杂计算来决定缩放 * @param path * @param maxImageSize * @return */ public static Bitmap decodeBitmap(String path,int maxImageSize){ BitmapFactory.Options op = new BitmapFactory.Options(); op.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodefile(path,op); //获取尺寸信息 int scale = 1; if(op.outWIDth > maxImageSize || op.outHeight > maxImageSize){ scale = (int)Math.pow(2,(int)Math.round(Math.log(maxImageSize/(double)Math.max(op.outWIDth,op.outHeight))/Math.log(0.5))); } op.inJustDecodeBounds = false; op.inSampleSize = scale; bmp = BitmapFactory.decodefile(path,op); return bmp; } public static Cursor querythumbnails(Activity context){ String[] columns = new String[]{ MediaStore.Images.thumbnails.DATA,MediaStore.Images.thumbnails._ID,MediaStore.Images.thumbnails.IMAGE_ID }; return context.managedquery(MediaStore.Images.thumbnails.EXTERNAL_CONTENT_URI,columns,null,MediaStore.Images.thumbnails.DEFAulT_SORT_ORDER); } public static Cursor querythumbnails(Activity context,String selection,String[] selectionArgs){ String[] columns = new String[]{ MediaStore.Images.thumbnails.DATA,selection,selectionArgs,MediaStore.Images.thumbnails.DEFAulT_SORT_ORDER); } public static Bitmap querythumbnailByID(Activity context,int thumbID){ String selection = MediaStore.Images.thumbnails._ID + " = ?"; String[] selectionArgs = new String[]{ thumbID+"" }; Cursor cursor = BitmapUtils.querythumbnails(context,selectionArgs); if(cursor.movetoFirst()){ String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.thumbnails.DATA)); cursor.close(); return BitmapUtils.decodeBitmap(path,100); }else{ cursor.close(); return null; } } public static Bitmap[] querythumbnailsByIDs(Activity context,Integer[] thumbIDs){ Bitmap[] bitmaps = new Bitmap[thumbIDs.length]; for(int i=0; i<bitmaps.length; i++){ bitmaps[i] = BitmapUtils.querythumbnailByID(context,thumbIDs[i]); } return bitmaps; } /** * 获取全部 * @param context * @return */ public static List<Bitmap> querythumbnailList(Activity context){ List<Bitmap> bitmaps = new ArrayList<Bitmap>(); Cursor cursor = BitmapUtils.querythumbnails(context); for(int i=0; i<cursor.getCount(); i++){ cursor.movetoposition(i); String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.thumbnails.DATA)); Bitmap b = BitmapUtils.decodeBitmap(path,100); bitmaps.add(b); } cursor.close(); return bitmaps; } public static List<Bitmap> querythumbnailListByIDs(Activity context,int[] thumbIDs){ List<Bitmap> bitmaps = new ArrayList<Bitmap>(); for(int i=0; i<thumbIDs.length; i++){ Bitmap b = BitmapUtils.querythumbnailByID(context,thumbIDs[i]); bitmaps.add(b); } return bitmaps; } public static Cursor queryImages(Activity context){ String[] columns = new String[]{ MediaStore.Images.Media._ID,MediaStore.Images.Media.DATA,MediaStore.Images.Media.disPLAY_name }; return context.managedquery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,MediaStore.Images.Media.DEFAulT_SORT_ORDER); } public static Cursor queryImages(Activity context,String[] selectionArgs){ String[] columns = new String[]{ MediaStore.Images.Media._ID,MediaStore.Images.Media.DEFAulT_SORT_ORDER); } public static Bitmap queryImageByID(Activity context,int imageID){ String selection = MediaStore.Images.Media._ID + "=?"; String[] selectionArgs = new String[]{ imageID + "" }; Cursor cursor = BitmapUtils.queryImages(context,selectionArgs); if(cursor.movetoFirst()){ String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)); cursor.close(); //return BitmapUtils.decodeBitmap(path,260,260); return BitmapUtils.decodeBitmap(path,220); //看看和上面这种方式的差别,看了,差不多 }else{ cursor.close(); return null; } } /** * 根据缩略图的ID获取对应的大图 * @param context * @param thumbID * @return */ public static Bitmap queryImageBythumbnailID(Activity context,Integer thumbID){ String selection = MediaStore.Images.thumbnails._ID + " = ?"; String[] selectionArgs = new String[]{ thumbID+"" }; Cursor cursor = BitmapUtils.querythumbnails(context,selectionArgs); if(cursor.movetoFirst()){ int imageID = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Images.thumbnails.IMAGE_ID)); cursor.close(); return BitmapUtils.queryImageByID(context,imageID); }else{ cursor.close(); return null; } } } 这样就实现了,类似百度图片浏览的效果。效果图如下:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android仿百度图片查看功能全部内容,希望文章能够帮你解决Android仿百度图片查看功能所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)