Android仿百度图片查看功能

我们知道,进入百度图片后,输入一个关键字后,首先看到的是很多缩略图,当我们点击某张缩略图时,我们就可以进入到大图显示页面,在大图显示页面,中包含了一个图片画廊,同时当前大图为刚刚我们点击的那张图片。现在我们看看在Android中如何实现类似的效果: 

创新互联公司专注于从化网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供从化营销型网站建设,从化网站制作、从化网页设计、从化网站官网定制、成都微信小程序服务,打造从化网络公司原创品牌,更为您提供从化网站排名全网营销落地服务。

首先,我们需要有一个控件来显示缩略图,这里没有什么比GridView更加合适了。 

配置文件如下: 

 
 
   
 

对于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 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; i0; 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 bitmaps = new ArrayList(); 
      thumbIds = new int[cursor.getCount()]; 
      for(int i=0; i 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来实现

 
 
   
   
 

然后,对应的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 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 queryThumbnailList(Activity context){ 
    List bitmaps = new ArrayList(); 
    Cursor cursor = BitmapUtils.queryThumbnails(context); 
    for(int i=0; i queryThumbnailListByIds(Activity context, int[] thumbIds){ 
    List bitmaps = new ArrayList(); 
    for(int i=0; i

这样就实现了,类似百度图片浏览的效果。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持创新互联。


分享题目:Android仿百度图片查看功能
当前网址:http://azwzsj.com/article/ipiise.html