2012年4月26日木曜日

[Android]スライドショーをつくってみる

長らくblogを更新しておりませんでした・・・。
こんにちは、@mogakanaです。とりあえず生きてます。

本日はスライドショー的なものをつくってみました。
SDカード直下にある画像を読み込んでループ表示をするだけの簡単なお仕事です。

というわけで、まずは準備。
以下の画像をSD直下に保存します。

手書きの画像。ちょっとかわいい(笑)
↑こういうのを自画自賛という。

ちなみに完成画面はこんな簡易なものになります。

まずはSDカード直下に保存されている画像を取得するメソッドを作成します。
このときは".png"で判断しています。
.jpegなどは容赦なく無視。

private ArrayAdapter getImageFile() {
 // adapter の作成
 ArrayAdapter adapter = new ArrayAdapter(this,
   android.R.layout.simple_spinner_item);

 // SDカードのディレクトリを取得
 File directory = Environment.getExternalStorageDirectory();

 // SDカードの一番上からファイルを取得
 File[] files = directory.listFiles();

 // adapterにファイルパスを追加
 for (int i = 0; i < files.length; i++) {
  // pngを追加
  if (files[i].getName().endsWith(".png")) {
   adapter.add(files[i].getPath());
  }
 }

 return adapter;
}
あとで使うのでadapterで返しています。
取得したSDの画像をスピナーへ。
SD直下になにも画像がなかったときは強制的にアプリを終了させてみました(おい)。

// SDのファイル取得
mFileSpinner = (Spinner) findViewById(R.id.fileSelectSpinner);

// adapterの作成
mFileSpinner.setAdapter(getImageFile());
mFileSpinner.setOnItemSelectedListener(this);

// ファイルがなかったときはアプリケーション終了
if(mFileSpinner.getChildCount() == 0) {
 Toast.makeText(this, "File Nothing! application close...", Toast.LENGTH_LONG).show();
 finish();
}
スタートボタンを押すとはじまります。

最初にmIsSlideShowというフラグをつくっておいてSTART/STOPを制御します。

private boolean mIsSlideShow = false;
では、スタートボタンの実装へ。

public void onClickShowButton(View view) {

 Button showButton = (Button) findViewById(R.id.showButton);

 if (mIsSlideShow) {
  // ストップ
  mHandler.sendEmptyMessage(0);
  showButton.setText("START");
 } else {
  // スタート
  mCurrentPosition = mFileSpinner.getSelectedItemPosition();
  showImageFile(mFileSpinner.getSelectedItemPosition());
  showButton.setText("STOP");
  mIsSlideShow = true;
  Thread thread = new Thread(this);
  thread.start();
 }

}
スレッドで制御しております。なぜなら、途中でストップを押すために。
その前に画像を表示させるメソッドを。

private void showImageFile(int position) {

 String selectFilePath = (String) mFileSpinner
   .getItemAtPosition(position);

 Bitmap bitmap = BitmapFactory.decodeFile(selectFilePath);
 mImageCanvas.setImageBitmap(bitmap);

}
スレッドはこうなります。

@Override
public void run() {
 while (mIsSlideShow) {
  try {
   // スリープ(10秒)
   Thread.sleep(10000);
  } catch (Exception e) {
   Log.e(TAG, "error!!");
  }

  Log.i(TAG, String.valueOf(mCurrentPosition));

  // 画像の変更
  if (mCurrentPosition == mFileSpinner.getCount() - 1) {
   // 先頭へ
   mCurrentPosition = 0;
  } else {
   mCurrentPosition++;
  }

  mHandler.post(new Runnable() {
   @Override
   public void run() {
    showImageFile(mCurrentPosition);
   }
  });

 }

}

private Handler mHandler = new Handler() {
 public void handleMessage(Message msg) {
  // 終了
  mIsSlideShow = false;
 }

};
ストップが押されるまで画像がループされます。

というわけで今日のソースはこちら。

package jp.co.mogakana.slideshow;

import java.io.File;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.Toast;

public class SlideShowActivity extends Activity implements
  OnItemSelectedListener, Runnable {

 private static final String TAG = "SlideShow";

 private int mCurrentPosition;

 private Spinner mFileSpinner;
 private ImageView mImageCanvas;

 private boolean mIsSlideShow = false;

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  mImageCanvas = (ImageView) findViewById(R.id.slideShowImageView);

  // SDのファイル取得
  mFileSpinner = (Spinner) findViewById(R.id.fileSelectSpinner);
  // adapterの作成
  mFileSpinner.setAdapter(getImageFile());

  mFileSpinner.setOnItemSelectedListener(this);
  
  
  // ファイルがなかったときはアプリケーション終了
  if(mFileSpinner.getChildCount() == 0) {
      Toast.makeText(this, "File Nothing! application close...", Toast.LENGTH_LONG).show();
      finish();
  }
  

 }

 public void onClickShowButton(View view) {

  Button showButton = (Button) findViewById(R.id.showButton);

  if (mIsSlideShow) {
   // ストップ
   mHandler.sendEmptyMessage(0);
   showButton.setText("START");
  } else {
   // スタート
   mCurrentPosition = mFileSpinner.getSelectedItemPosition();
   showImageFile(mFileSpinner.getSelectedItemPosition());
   showButton.setText("STOP");
   mIsSlideShow = true;
   Thread thread = new Thread(this);
   thread.start();
  }

 }

 private void showImageFile(int position) {

  String selectFilePath = (String) mFileSpinner
    .getItemAtPosition(position);

  Bitmap bitmap = BitmapFactory.decodeFile(selectFilePath);
  mImageCanvas.setImageBitmap(bitmap);

 }

 private ArrayAdapter getImageFile() {
  // adapter の作成
  ArrayAdapter adapter = new ArrayAdapter(this,
    android.R.layout.simple_spinner_item);

  // SDカードのディレクトリを取得
  File directory = Environment.getExternalStorageDirectory();

  // SDカードの一番上からファイルを取得
  File[] files = directory.listFiles();

  // adapterにファイルパスを追加
  for (int i = 0; i < files.length; i++) {
   // pngを追加
   if (files[i].getName().endsWith(".png")) {
    adapter.add(files[i].getPath());
   }
  }

  return adapter;
 }

 @Override
 public void onItemSelected(AdapterView arg0, View arg1, int position,
   long arg3) {

 }

 @Override
 public void onNothingSelected(AdapterView arg0) {
  Toast.makeText(this, "File Nothing!", Toast.LENGTH_LONG).show();
 }

 @Override
 public void run() {
  while (mIsSlideShow) {
   try {
    // スリープ(10秒)
    Thread.sleep(10000);
   } catch (Exception e) {
    Log.e(TAG, "error!!");
   }

   Log.i(TAG, String.valueOf(mCurrentPosition));

   // 画像の変更
   if (mCurrentPosition == mFileSpinner.getCount() - 1) {
    // 先頭へ
    mCurrentPosition = 0;
   } else {
    mCurrentPosition++;
   }

   mHandler.post(new Runnable() {
    @Override
    public void run() {
     showImageFile(mCurrentPosition);
    }
   });

  }

 }

 private Handler mHandler = new Handler() {
  public void handleMessage(Message msg) {
   // 終了
   mIsSlideShow = false;
  }

 };

 @Override
 protected void onResume() {
  super.onResume();
  
 }

 @Override
 protected void onPause() {
  super.onPause();
 }

}
適当に書いたんだけど、けっこう絵がかわいいと自画自賛中。