画像ダウンロード中にローディングっぽい表示を出しておきたい
という需要が良くあるのだけど、標準のSDKのライブラリにはピッタリのものがないので、それっぽいものを書いてみた。
まず、画面のレイアウト。今回はListActivityを使うのでそのように。今回の本筋とは関係ない。
- layout/main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ListView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@android:id/list" /> </LinearLayout>
こちらは、ProgressBarのくるくる回るやつ用のlayout. codingではこのstyleが指定できないので仕方なくlayoutで。
- layout/loading
<?xml version="1.0" encoding="utf-8"?> <ProgressBar xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" style="?android:attr/progressBarStyle" />
で、Javaのコード。キモはImageBox class。
package com.komamitsu.hogedoroid; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import android.app.ListActivity; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.ViewFlipper; class ImageBox extends ViewFlipper { private final ImageView image; private final String imageUrl; private Status status = Status.INIT; private enum Status { INIT, LOADING, LOADED }; public ImageBox(Context context, String imageUrl) { super(context); this.imageUrl = imageUrl; LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(R.layout.loading, this); image = new ImageView(context); addView(image); } public void draw() throws IOException { if (imageUrl == null) return; switch (status) { case INIT: if (getDisplayedChild() == 1) showPrevious(); LodingTask lt = new LodingTask(imageUrl); lt.execute(); status = Status.LOADING; break; case LOADING: break; case LOADED: break; } } private class LodingTask extends AsyncTask<Void, Drawable, Void> { private final String url; LodingTask(String url) { super(); this.url = url; } @Override protected Void doInBackground(Void... params) { URL url; try { url = new URL(this.url); Drawable drawable = Drawable.createFromStream((InputStream)url.getContent(), "src"); publishProgress(drawable); } catch (MalformedURLException e) { Log.e(getClass().getName(), "MalformedURLException " + e == null ? "" : e.getMessage()); } catch (IOException e) { Log.e(getClass().getName(), "IOException " + e == null ? "" : e.getMessage()); } return null; } @Override protected void onProgressUpdate(Drawable... values) { image.setImageDrawable(values[0]); if (getDisplayedChild() == 0) { showNext(); } status = ImageBox.Status.LOADED; } } } class HogeListAdapter extends ArrayAdapter<ImageBox> { public HogeListAdapter(Context context, int textViewResourceId, List<ImageBox> objects) { super(context, textViewResourceId, objects); } @Override public View getView(int position, View convertView, ViewGroup parent) { ImageBox imageBox = getItem(position); try { imageBox.draw(); } catch (IOException e) { Log.e(getClass().getName(), "IOException " + e == null ? "" : e.getMessage()); } return imageBox; } } public class Main extends ListActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); List<String> urls = Arrays.asList( "http://www.bestfreeicons.com/smimages/walking-icon.png", "http://www.bestfreeicons.com/smimages/seniors-icon.png", "http://www.bestfreeicons.com/smimages/reading-icon.png", "http://www.bestfreeicons.com/smimages/glasses-icon.png", "http://www.bestfreeicons.com/smimages/family-icon.png", "http://www.bestfreeicons.com/smimages/walking-icon.png", "http://www.bestfreeicons.com/smimages/seniors-icon.png", "http://www.bestfreeicons.com/smimages/reading-icon.png", "http://www.bestfreeicons.com/smimages/glasses-icon.png", "http://www.bestfreeicons.com/smimages/family-icon.png" ); List<ImageBox> imageBoxes = new ArrayList<ImageBox>(); for (String url : urls) { imageBoxes.add(new ImageBox(this, url)); } setListAdapter(new HogeListAdapter(this, 0, imageBoxes)); }
これを起動させると、List上で各画像をダウンロードしようとするのだけど、最初はクルクルしていて、ダウンロード後に切り替わる。読み込みに失敗したら失敗画像でもセットしておけば、より良さげ。
画像を貼り付けようかと思ったけど、ローディング中の間にキャプチャするのに二回失敗したので、風呂に入ってフテ寝することに。