您好,登錄后才能下訂單哦!
我們知道,進(jìn)入百度圖片后,輸入一個(gè)關(guān)鍵字后,首先看到的是很多縮略圖,當(dāng)我們點(diǎn)擊某張縮略圖時(shí),我們就可以進(jìn)入到大圖顯示頁(yè)面,在大圖顯示頁(yè)面,中包含了一個(gè)圖片畫廊,同時(shí)當(dāng)前大圖為剛剛我們點(diǎn)擊的那張圖片?,F(xiàn)在我們看看在Android中如何實(shí)現(xiàn)類似的效果:
首先,我們需要有一個(gè)控件來(lái)顯示縮略圖,這里沒(méi)有什么比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>
對(duì)于GridView中每一項(xiàng)是一張縮略圖,我們需要繼承BaseAdapter,實(shí)現(xiàn)自己的一個(gè)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) { // 點(diǎn)擊事件 showCurrentImage(position); } }; private void init(){ thumbIds = this.getIntent().getIntArrayExtra("thumbIds"); currentPos = this.getIntent().getIntExtra("currentPos",0); //galleryIds = this.getThumbnailIds(currentPos); //當(dāng)前的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當(dāng)前可見(jiàn)的顯示之前的3張,后3張緩存起來(lái),其余的釋放掉,這樣是為了放置內(nèi)存不夠用 * 之所以前三張后三張,是為了Gallery可以滑動(dòng)的更加順暢 */ private void releaseBitmaps(){ int start = gallery.getFirstVisiblePosition()-3; //緩存的起始位置 int end = gallery.getLastVisiblePosition()+3; //緩存的結(jié)束位置 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(); } } } /** * 獲取當(dāng)前位置的前三個(gè)Id和后三個(gè)Id * @param position * @return */ private Integer[] getThumbnailIds(int position){ Integer[] ids = new Integer[]{0,0,0,0,0,0,0}; int currPos = 0; //關(guān)于這里的處理,比較復(fù)雜 for(int i=3; i>0; i--){ if(position - i >= 0){ currPos = 3-i; ids[currPos] = thumbIds[position-i]; } } ids[++currPos] = thumbIds[position]; //當(dāng)前Id //currGallerySelection = currPos; //這樣右邊剩下的位置數(shù)就是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中通過(guò)查詢MediaStore的多媒體圖片庫(kù)來(lái)查詢所有的圖片的縮略圖,縮略圖所在的位置是:
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) { //點(diǎn)擊某張縮略圖時(shí),轉(zhuǎn)到圖片顯示界面 Intent intent = new Intent(); intent.setClass(MainActivity.this, GalleryActivity.class); intent.putExtra("thumbIds", thumbIds); intent.putExtra("currentPos", position); startActivity(intent); } }; }
注意到,我們記錄了,所有縮略圖對(duì)應(yīng)的id號(hào),和當(dāng)前的用戶選擇的位置,然后通過(guò)Intent傳遞到第二個(gè)展示界面。第二個(gè)界面的布局文件如下:我們用了一個(gè)Gallery和一個(gè)ImageButton來(lái)實(shí)現(xiàn)
<?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>
然后,對(duì)應(yīng)的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) { // 點(diǎn)擊事件 showCurrentImage(position); } }; private void init(){ thumbIds = this.getIntent().getIntArrayExtra("thumbIds"); currentPos = this.getIntent().getIntExtra("currentPos",0); //galleryIds = this.getThumbnailIds(currentPos); //當(dāng)前的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(); } }
可以看到,當(dāng)用戶點(diǎn)擊Gallery中某一項(xiàng)時(shí),觸發(fā)onItemClick事件,在其中,我們通過(guò)根據(jù)該縮略圖對(duì)應(yīng)的Image_ID來(lái)從MediaStore.Images.Media中查詢?cè)摽s略圖對(duì)應(yīng)的大圖。并在ImageButton中顯示。
這里當(dāng)圖片很多時(shí),可能會(huì)出現(xiàn)內(nèi)存溢出,為了避免這種情況,可以更加Gallery的特點(diǎn),使用緩存。保存當(dāng)前可見(jiàn)的縮略圖的前三個(gè)到后三個(gè)。其余的全部recycle。當(dāng)用戶點(diǎn)擊Gallery的時(shí)候,在判斷當(dāng)前的位置,如果大于或小于某個(gè)值時(shí),則重新更新緩存。這樣保證內(nèi)存中的縮略圖的個(gè)數(shù)總是6+Gallery.getLastVisiblePosition-Gallery.getFirstVisiblePosition個(gè)。其實(shí)這就是浮動(dòng)緩存窗口,一個(gè)固定大小窗口在整個(gè)坐標(biāo)(全部縮略圖)上游動(dòng)。這里沒(méi)有實(shí)現(xiàn),以后待續(xù)。
同時(shí),你可能已經(jīng)注意到,程序中使用到了一個(gè)BitmapUtils類,這個(gè)類是封裝了一系列對(duì)查詢圖片,并將其解析為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); //如果超出指定大小,則縮小相應(yīng)的比例 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); } /** * 采用復(fù)雜計(jì)算來(lái)決定縮放 * @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; } } /** * 根據(jù)縮略圖的Id獲取對(duì)應(yīng)的大圖 * @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; } } }
這樣就實(shí)現(xiàn)了,類似百度圖片瀏覽的效果。效果圖如下:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。