前面的Android應用中已經大量使用了簡單圖片,圖片不只可使用ImageView來顯示,也可做爲Butto、Window的背景。從廣義的角度來看,Android應用中的圖片不只包括*.png、*.jpg、*.gif等各類格式的位圖,也包括使用XML資源定義的各類Drawable對象。java
使用Drawable對象android
爲Android應用增長了Drawable資源以後,Android SDK會爲這份資源在R清單文件中建立一個索引項:R.drawable.file_name。數組
接下來既可在XML資源文件中經過@drawable/file_name來訪問該Drawable對象,也可在Java代碼中經過R.drawable.file_name來訪問該Drawable對象。app
須要指出的是,R.drawable.file_name是一個int類型的常量,它只表明Drawable對象的ID,若是Java程序中須要獲取實際的Drawable對象,既可調用Resources的getDrawable(int id)方法來獲取。ide
Bitmap和BitmapFactory工具
Bitmap表明一張位圖,BitmapDrawable裏封裝的圖片就是一個Bitmap對象。開發者爲了把一個Bitmap對象包裝成BitmapDrawable對象,能夠調用BitmapDrawable的構造器:佈局
//把一個Bitmap對象包裝成BitmapDrawable對象this
BitmapDrawable drawable=new BitmapDrawable(bitmap);spa
若是須要獲取BitmapDrawable所包裝的Bitmap對象,則可調用BitmapDrawable的getBitmap()方法,以下面代碼所示:code
//獲取一個BitmapDrawable所包裝的Bitmap對象
Bitmap bitmap=drawable.getBitmap();
除此以外,Bitmap還提供了一些靜態方法來建立新的Bitmap對象,例如以下經常使用方法。
BitmapFactory是一個工具類,它用於提供大量的方法,這些方法可用於從不一樣的數據源來解析、建立Bitmap對象。BitmapFactory包含了以下方法。
大部分時候,咱們只要把圖片放在/res/drawable-mdpi目錄下,就能夠在程序中經過該圖片對應的資源ID來獲取封裝該圖片的Drawble對象。但因爲手機系統的內存比較小,若是系統不停的去解析、建立Bitmap對象,可能因爲前面建立Bitmap所佔用的內存尚未回收,而致使程序運行時引起OutOfMemory錯誤。
Android爲Bitmap提供了兩個方法來判斷他是否已回收,以及強制Bitmap回收本身。
除此以外,若是Android應用須要訪問其餘存儲路徑(好比SD卡中)裏的圖片,都須要藉助於BitmapFactory來解析、建立Bitmap對象。
下面開發一個查看/assets/目錄下圖片的圖片查看器,該程序界面十分簡單,只包含一個ImageView和一個按鈕,但用戶單擊該按鈕時程序會自動搜尋/assets/目錄下的下一張圖片。
界面佈局代碼以下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:id="@+id/next" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="下一張圖片"/> <ImageView android:id="@+id/image" android:layout_width="fill_parent" android:layout_height="wrap_content" android:scaleType="fitCenter"/> </LinearLayout>
該程序的代碼以下:
package com.example.studydrawable; import java.io.IOException; import java.io.InputStream; import android.os.Bundle; import android.app.Activity; import android.content.res.AssetManager; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class BitmapTest extends Activity { String[] images=null; AssetManager assets=null; int currentImg=0; ImageView image; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_bitmap_test); image=(ImageView)findViewById(R.id.image); try{ assets=getAssets(); //獲取/assets/目錄下全部文件 images=assets.list(""); } catch(IOException e) { e.printStackTrace(); } //獲取bn按鈕 final Button next=(Button)findViewById(R.id.next); //爲bn按鈕綁定事件監聽器,該監聽器將會查看下一張圖片 next.setOnClickListener(new OnClickListener(){ @Override public void onClick(View source) { // TODO Auto-generated method stub //若是發生數組越界 if(currentImg>=images.length) { currentImg=0; } //找到下一張圖片 while(!images[currentImg].endsWith(".png") &&!images[currentImg].endsWith(".jpg") &&!images[currentImg].endsWith(".gif")) { currentImg++; //若是已經發生數組越界 if(currentImg>=images.length) { currentImg=0; } } InputStream assetFile=null; try { //打開指定資源對應的輸入流 assetFile=assets.open(images[currentImg++]); } catch(IOException e) { e.printStackTrace(); } BitmapDrawable bitmapDrawable=(BitmapDrawable)image.getDrawable(); //若是圖片還未回收,先強制回收該圖片 if(bitmapDrawable!=null&&!bitmapDrawable.getBitmap().isRecycled())//① { bitmapDrawable.getBitmap().recycle(); } //改變ImageView顯示的圖片 image.setImageBitmap(BitmapFactory.decodeStream(assetFile));//② }}); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.bitmap_test, menu); return true; } }
上面程序中①號粗體字代碼用於判斷當前ImageView所顯示的圖片是否已被回收,若是該圖片還未回收,系統強制回收該圖片;程序的②好粗體字代碼調用了BitmpFactory從指定輸入流解析、並建立Bitmap對象。