软件编程
位置:首页>> 软件编程>> Android编程>> Android仿百度图片查看功能

Android仿百度图片查看功能

作者:chenjie19891104  发布时间:2023-09-26 07:50:24 

标签:Android,图片查看

我们知道,进入百度图片后,输入一个关键字后,首先看到的是很多缩略图,当我们点击某张缩略图时,我们就可以进入到大图显示页面,在大图显示页面,中包含了一个图片画廊,同时当前大图为刚刚我们点击的那张图片。现在我们看看在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,0,0,0,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, View v, int position,
       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, 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中某一项时,触发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, 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,
       MediaStore.Images.Thumbnails._ID,
       MediaStore.Images.Thumbnails.IMAGE_ID
   };
   return context.managedQuery(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, columns, 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,selection,selectionArgs);

if(cursor.moveToFirst()){
     String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA));
     cursor.close();
     return BitmapUtils.decodeBitmap(path, 100, 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, 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, columns, null, null, MediaStore.Images.Media.DEFAULT_SORT_ORDER);
 }

public static Cursor queryImages(Activity context, String selection, String[] selectionArgs){
   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, columns, selection, selectionArgs, 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, selection, 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, selection, 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仿百度图片查看功能

来源:http://blog.csdn.net/chenjie19891104/article/details/6336439

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com