2013年9月18日水曜日

GridViewを使ってみる(SDカードの画像表示)

前回の「GridViewを使ってみる(Adapterのカスタマイズ) 」では、
AdapterをカスタマイズしたCustomAdapterを利用して文字列をセットして扱いました。

今回は、文字列ではなくBitmapを扱い、画像を表示させたいと思います( ̄ー ̄)ニヤリ
画像はAVDのSDカードに画像を追加してその画像を利用したいと思います。

AVDのSDカードに画像を追加する方法はこちらに記載してあります
AVDのSDカードにデータを登録する

■AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.gridview2"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="8" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.gridview2.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


■activity_main.xml

    
    


■grid.xml
GridView用のレイアウトファイルになります。
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

</ImageView>

■MainActivity.java

BitmapFactory.Optionsについて次の記事が参考になりました。
Android 大きい画像を効果的に読み込む
デコーダーに画像をサブサンプルさせる(縮小して読み込む、低解像度で読み込む)には、
BitmapFactory.Options の inSampleSize パラメータに 1 より大きい整数値を指定します。
(原文ではなぜか true をセットと書いてありますが間違いです)

inSampleSize に 1 より大きい整数値を指定すると、縦横それぞれが約 1 / inSampleSize になって読み込まれます。
例えば

元 : 2048 x 1536
|
inSampleSize = 4

Bitmap : 512 x 384

縦横がそれぞれ 1 / inSampleSize になるので、サイズは 1 / inSampleSize^2 になります。

表示するサイズから inSampleSize を求めるにはこうします。

には、BitmapFactory.Options の inSampleSize パラメータに 1 より大きい整数値を指定します。
package com.example.gridview2;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.widget.GridView;

public class MainActivity extends Activity {

 // ディレクトリ格納用
 private List<String> directory = new ArrayList<String>(); 

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  // SDカードから画像を取り出す。
  ArrayList<Bitmap> list = getImages();
  // カスタムアダプターの生成
  CustomAdapter adapter = new CustomAdapter(getApplicationContext(),
    R.layout.grid, list);
  // GridViewを取得する
  GridView gridView = (GridView) findViewById(R.id.gridView1);
  // GridViewにAdapterを設定する
  gridView.setAdapter(adapter);

 }

 /*
  * SDカードから画像を取り出す。
  */
 private ArrayList<Bitmap> getImages() {

  //
  ArrayList<Bitmap> list = new ArrayList<Bitmap>();

  // 外部ストレージ(SDカード)のデレクトリPATHを取得
  File file = Environment.getExternalStorageDirectory();

  // 参照ベースディレクトリ
  directory.add(file.getPath());

  // 指定ディレクトリ内のファイル検索
  int lengthSubDirectory = 0;
  int lengthDirectory = directory.size();
  String filePathImage = "";
  for (int i = 0; i < lengthDirectory; i++) {

   // 指定されたディレクトリ情報を取得する
   File directorySub = new File((String) directory.get(i));

   // ファイル/ディレクトリ一覧を取得する
   String[] subFileName = directorySub.list();

   // ファイル/ディレクトリが無かった場合
   if (subFileName == null) {
    continue;
   }

   // 件数を取得する
   lengthSubDirectory = subFileName.length;
   for (int j = 0; j < lengthSubDirectory; j++) {

    // ディレクトリの中身のファイル(ディレクトリも含まれる)を取得する
    File subFile = new File(directorySub.getPath() + "/"
      + subFileName[j]);

    if (subFile.isDirectory()) {

     // サブディレクトリならループ末尾に追加して検索する
     directory.add(directorySub.getPath() + "/"
       + subFileName[j]);

    } else if (isImage(subFile)) {

     // 画像ファイルの場合には表示対象に追加

     // ビットマップ変換
     filePathImage = directorySub.getPath() + "/"
       + subFileName[j];

     File fileImage = new File(filePathImage);
     // オプション設定
     BitmapFactory.Options bmpOp = new BitmapFactory.Options();
     // 低解像度で読み込む。値が大きいほど低画像(サイズ、解像度が低く)になる。
     bmpOp.inSampleSize = 5;
     //
     list.add(BitmapFactory.decodeFile(fileImage.getPath(),
       bmpOp));

    }

   }
  }
  //
  return list;
 }

 /*
  * 画像の拡張子かチェックする
  * 
  * @return Boolean
  */
 protected boolean isImage(File checkedFile) {

  // チェック結果
  boolean checkResultFlag = false;

  // 画像拡張子リスト
  final String[] IMAGE_EXTENSION_ARRAY = { ".bmp", ".gif", ".jpg",
    ".jpeg", ".png" };

  // nullチェック
  if (checkedFile == null) {
   return checkResultFlag;
  }

  // isFileチェック
  if (!checkedFile.isFile()) {
   return checkResultFlag;
  }

  // ファイル名取得チェック
  if (checkedFile.getName() == null
    || checkedFile.getName().length() == 0) {
   return checkResultFlag;
  }

  // ファイルの末尾が画像拡張子リストの中にあるかチェック
  for (int i = 0; i < IMAGE_EXTENSION_ARRAY.length; i++) {
   if (checkedFile.getName().endsWith(
     IMAGE_EXTENSION_ARRAY[i].toLowerCase())
     || checkedFile.getName().endsWith(
       IMAGE_EXTENSION_ARRAY[i].toUpperCase())) {
    checkResultFlag = true;
    break;
   }
  }

  return checkResultFlag;
 }

}

■CustomAdapter.java
package com.example.gridview2;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;

public class CustomAdapter extends ArrayAdapter<Bitmap> {

 //
 private Context context = null;
 // アダプターに渡したリスト
 private ArrayList<Bitmap> data = null;
 //
 private int resource = 0;

 public CustomAdapter(Context context, int resource, ArrayList<Bitmap> data) {
  super(context, resource, data);
  //
  this.context = context;
  this.resource = resource;
  this.data = data;
 }

 /*
  * 指定された項目を識別するためのIDを取得する
  */
 @Override
 public long getItemId(int position) {
  return position;
 }

 /*
  * 指定された項目を取得する
  */
 @Override
 public Bitmap getItem(int position) {
  return data.get(position);
 }

 /*
  * データの項目数を取得する
  */
 @Override
 public int getCount() {
  return data.size();
 }

 /*
  * 1アイテム分のビューを取得.
  * @param Integer
  *   アイテムのポジション番号
  * @param View
  *    可能な場合不要なビューを再利用する。膨大な量の情報を出力する場合にオブジェクトを可能な限り再利用する。
  *    nullの場合には再利用できるオブジェクトがないためオブジェクトを生成する。
  * 
  * @param ViewGroup
  *    選択されたAdapterのビューとなる。GridViewになる。
  * 
  */
 @Override
 public View getView(int position, View convertView, ViewGroup parent) {

  // Viewが無かった場合
  if (convertView == null) {
   // コンストラクタで渡されたレイアウトのリソースIDからViewを取得するため、LayoutInflaterを取得する
   LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   // レイアウトファイルをViewに変換する(レイアウトに記述されているルートのViewになる)
   convertView = inflater.inflate(resource, null);
  }
  // 取得したビューのキャスト
  ImageView view = (ImageView) convertView;
  // ImageViewに画像を設定する
  view.setImageBitmap(getItem(position));

  return view;
 }

}
実行結果は次のようになります。

以上です(`・ω・´)ゞビシッ!!

参考URL

0 件のコメント:

コメントを投稿