下面是一个完整的示例,它查询MediaStore以发现图像,并以幻灯片的形式一幅接一幅的向用户展示图像。
1 package com.nthm.androidtest; 2 3 import android.support.v7.app.ActionBarActivity; 4 import android.widget.ImageButton; 5 import android.widget.TextView; 6 import android.database.Cursor; 7 import android.graphics.Bitmap; 8 import android.graphics.BitmapFactory; 9 import android.os.Bundle; 10 import android.provider.MediaStore.Images.Media; 11 12 public class MediaStoreGallery extends ActionBarActivity { 13 public final static int DISPALYWIDTH=200; 14 public final static int DISPALYHEIGHT=200;
没有使用屏幕大小来加载和显示图像,我们将使用上述的常量来决定如何显示他们。
1 private TextView titleTextView; 2 private ImageButton imageButton;
在此示例中,使用一个ImageButton来代替ImageView。则会使得我们同事具有Button的功能(可单击)和ImageView的功能(可显示一幅图像)。
1 private Cursor cursor; 2 private Bitmap bmp; 3 private String imageFilePath; 4 private int fileColumn; 5 private int titleColumn; 6 private int displayColumn; 7 @Override 8 protected void onCreate(Bundle savedInstanceState) { 9 super.onCreate(savedInstanceState); 10 setContentView(R.layout.mediastoregallery); 11 titleTextView=(TextView) findViewById(R.id.TitleTextView); 12 imageButton=(ImageButton) findViewById(R.id.ImageButton);
一下代码指定了想要返回的列,它必须是字符串的形式。在下面的代码中将这个数组传递给managedQuery方法。
1 String [] columns={Media.DATA,Media._ID,Media.TITLE,Media.DISPLAY_NAME}; 2 cursor=managedQuery(Media.EXTERNAL_CONTENT_URI, columns, null, null, null);
我们将需要知道从Cursor对象获取数据的每个列的索引,在此示例中,从Media.DATA切换到MediaStore.Images.Media.DATA。这仅仅是为了说明他们是相同的。Media.DATA仅仅是可以使用的简写形式,因为有一条包含他的import语句:import android.provider.MediaStore.Images.Media。
1 fileColumn=cursor.getColumnIndexOrThrow(Media.DATA); 2 titleColumn=cursor.getColumnIndexOrThrow(Media.TITLE); 3 displayColumn=cursor.getColumnIndexOrThrow(Media.DISPLAY_NAME);
运行查询并获得一个结果Cursor对象之后,调用该对象上的moveToFirst方法,以确保它包含结果。
1 if(cursor.moveToFirst()){ 2 titleTextView.setText(cursor.getString(displayColumn)); 3 imageFilePath=cursor.getString(fileColumn); 4 bmp=getBitmap(imageFilePath); 5 //显示图像 6 imageButton.setImageBitmap(bmp); 7 }
然后,为imageButton指定一个新的OnClickListener,其调用Cursor对象上的moveToNext方法。它将遍历结果集,获取并显示返回的每幅图像。
1 imageButton.setOnClickListener(new OnClickListener() { 2 3 @Override 4 public void onClick(View v) { 5 if(cursor.moveToNext()){ 6 titleTextView.setText(cursor.getString(displayColumn)); 7 imageFilePath=cursor.getString(fileColumn); 8 bmp=getBitmap(imageFilePath); 9 //显示图像 10 imageButton.setImageBitmap(bmp); 11 } 12 } 13 });
下面的getBitmap的方法,它封闭了图像的缩放和加载的功能。这么做是为了在显示这些图像时避免产生本章前面所讨论的内存问题。
1 private Bitmap getBitmap(String imageFilePath){ 2 //加载图像的尺寸而非图像的本身 3 BitmapFactory.Options bmpBitmapFactoryOptions=new BitmapFactory.Options(); 4 bmpBitmapFactoryOptions.inJustDecodeBounds=true; 5 Bitmap bmp=BitmapFactory.decodeFile(imageFilePath, bmpBitmapFactoryOptions); 6 int heightRatio=(int) Math.ceil(bmpBitmapFactoryOptions.outHeight/(float)DISPALYHEIGHT); 7 int widthRatio=(int) Math.ceil(bmpBitmapFactoryOptions.outWidth/(float)DISPALYWIDTH); 8 //如果两个比率都大于1 那么图像的一条边大于屏幕 9 if(heightRatio>1&&widthRatio>1){ 10 if(heightRatio>widthRatio){ 11 //若高度比率比较大,则根据它进行缩放 12 bmpBitmapFactoryOptions.inSampleSize=heightRatio; 13 }else{ 14 //若宽度比率比较大,则根据它进行缩放 15 bmpBitmapFactoryOptions.inSampleSize=widthRatio; 16 } 17 } 18 //对它进行真正的解码 19 bmpBitmapFactoryOptions.inJustDecodeBounds=false; 20 bmp=BitmapFactory.decodeFile(imageFilePath, bmpBitmapFactoryOptions); 21 return bmp; 22 }
下面是与上述活动对应的布局XML,应该将它放在res/layout/mediastoregallery.xml文件中
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="match_parent" 3 android:layout_height="match_parent" 4 android:orientation="vertical" 5 > 6 <ImageButton 7 android:layout_width="wrap_content" 8 android:layout_height="wrap_content" 9 android:id="@+id/ImageButton" 10 /> 11 <TextView 12 android:id="@+id/TitleTextView" 13 android:layout_width="match_parent" 14 android:layout_height="wrap_content" 15 android:text="Image Title" /> 16 17 </LinearLayout>