使用簡單圖片

      前面的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對象,例如以下經常使用方法。

  •  createBitmap(Bitmap source,int x,int y,int width,int height):從源位圖source的指定座標點(給定x、y)開始,從中「挖取」寬width、高height的一塊出來,建立新的Bitmap對象。
  • createScaledBitmap(Bitmap src,int dstWidth,int dstHeight,boolean filter):對源位圖src進行縮放,縮放成寬dstWidth、高dstHeight的新位圖。
  • createBitmap(int width,int height,Bitmap.Config config):建立一個寬width、高height的新位圖。
  • createBitmap(Bitmap source,int x,int y,int width,int height,Matrix m,boolean filter):從源位圖source的指定座標點(給定x,y)開始,從中「挖取」寬width、高height的一一塊出來,建立新的Bitmap對象。並按Matrix指定的規則進行變換。    

    BitmapFactory是一個工具類,它用於提供大量的方法,這些方法可用於從不一樣的數據源來解析、建立Bitmap對象。BitmapFactory包含了以下方法。

  • decodeByteArray(byte[] data,int offset,int length):從指定字節數組的offset位置開始,將長度爲lenth的字節數組解析成Bitmap對象。
  • decodeFile(String pathName):從pathName指定的文件中解析、建立Bitmap對象。
  • decodeFileDescriptor(FileDescriptor fd):用於從FieDescriptor對應的文件中解析、建立Bitmap對象。
  • decodeResource(Resource res,int id):用於根據給定的資源ID從指定的資源中解析、建立Bitmap對象。 
  • decodeStream(InputStream is):用於從指定輸入流中解析、建立Bitmap對象。

      大部分時候,咱們只要把圖片放在/res/drawable-mdpi目錄下,就能夠在程序中經過該圖片對應的資源ID來獲取封裝該圖片的Drawble對象。但因爲手機系統的內存比較小,若是系統不停的去解析、建立Bitmap對象,可能因爲前面建立Bitmap所佔用的內存尚未回收,而致使程序運行時引起OutOfMemory錯誤。

     Android爲Bitmap提供了兩個方法來判斷他是否已回收,以及強制Bitmap回收本身。

  • boolean isRecycled():返回該Bitmap對象是否已被回收。
  • void recycle():強制一個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對象。

相關文章
相關標籤/搜索