sqliteから取得したurlで画像をlistviweに表示する


###やりたいこと
sqliteから情報を取得しListViewに表示。そのとき、画像情報はURLを元に、Volleyでネットから取ってくる。

####必要なファイル（クラス）

1. MyActivity.java　メイン。
2. MyDbHelper.java　DBHelper
3. Member.java ListViewで表示するデータ。ArrayListで使う。
4. MemberAdapter.java カスタムアダプター（肝）。
5. MyLruCache.java キャッシュクラス。ImageLoaderの引数に必要（まるまるコピペ）

###コード
VolleyのRequestQueueを引数としてadapterに渡すあたり。
Cursorの開放がきなる。CursorAdapterを改良するほうがいいかもしれませんが、JSONからデータを取得した場合とコードを同じにしたかったので、ArrayAdapterを継承。

```MyActivity.java
public class MyActivity extends Activity {

    ListView myListView;
    RequestQueue queue;

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

        //queue for imageLoader
        queue = Volley.newRequestQueue(this);

        //db
        MyDbHelper mDbHelper = new MyDbHelper(this);
        SQLiteDatabase db = mDbHelper.getWritableDatabase();

        //array list
        ArrayList<Member> members = new ArrayList<Member>();

        //select
        Cursor c = db.rawQuery("select * from members",null);

        //loop(building arraylist<member>)
        while(c.moveToNext()){

            Log.v("tama", c.getString(c.getColumnIndex("name")));

            //add arraylist
            Member member = new Member();

            member.setImage(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
            member.setName(c.getString(c.getColumnIndex("name")));
            member.setAge(c.getInt(c.getColumnIndex("age")));
            member.setUrl(c.getString(c.getColumnIndex("url")));

            members.add(member);
        }

        //adapter
        MemberAdapter adapter = new MemberAdapter(this,0,members,queue);

        //listview
        myListView = (ListView)findViewById(R.id.myListView);
        //bindして表示
        myListView.setAdapter(adapter);
        //クリックしたとき各行のデータ（特に_id）を取得
        myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

                //
                String s1 = ((TextView)view.findViewById(R.id.txtName)).getText().toString();
                String s2 = ((TextView)view.findViewById(R.id.txtAge)).getText().toString();

                Log.v("tama","position=" + s1);
                Log.v("tama","position=" + s2);
            }
        });

    }

    @Override
    protected void onResume(){
        super.onResume();
        if(queue!=null){
            queue.start();
        }
    }

    @Override
    protected void onPause(){
        super.onPause();
        if(queue!=null){
            queue.stop();
        }
    }
}
```
特に説明なし。ぜんぶ静的に書いてます。。。

```MyDbHelper.java
public class MyDbHelper extends SQLiteOpenHelper {

    public MyDbHelper(Context context){
        super(context,"test.db",null,2);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {

        //create
        sqLiteDatabase.execSQL("create table members(_id integer primary key autoincrement,name text,age integer,url text)");

        //init
        sqLiteDatabase.execSQL("insert into members(name,age,url) values('hoge',23,'http://www.bluecode.jp/test/image/001.jpg')");
        sqLiteDatabase.execSQL("insert into members(name,age,url) values('foo',34,'http://www.bluecode.jp/test/image/002.jpg')");
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i2) {

        //delete
        sqLiteDatabase.execSQL("drop table if exists members");

        //create
        onCreate(sqLiteDatabase);

    }
}
````

特に説明なし。

```Member.java
public class Member {

    //declear
    private Bitmap image;
    private String name;
    private int age;
    private String url;

    //set

    //image
    public Bitmap getImage(){
        return this.image;
    }

    public void setImage(Bitmap image){
        this.image = image;
    }

    //name
    public String getName(){
        return this.name;
    }

    public void setName(String name){
        this.name = name;
    }

    //age
    public int getAge(){
        return this.age;
    }

    public void setAge(int age){
        this.age = age;
    }

    //url
    public String getUrl(){
        return this.url;
    }

    public void setUrl(String url){
        this.url = url;
    }
}
```
RequestQueueを引数に受ける。コンストラクタ内で初期化。
getView()の中身が肝なのかな。

```MemberAdapter.java
public class MemberAdapter extends ArrayAdapter<Member> {

    //Inflater
    private LayoutInflater layoutInflater;
    private ImageLoader imageLoader;

    //constructor
    public MemberAdapter(Context context, int resource,ArrayList<Member> members,RequestQueue queue) {
        super(context, resource, members);
        imageLoader = new ImageLoader(queue,new MyLruCache());
        this.layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public View getView(int position,View convertView, ViewGroup parent){

        ViewHolder viewHolder;

        //最初 or 再利用するものがなかったら
        if(convertView == null){
            //レイアウトを指定
            convertView = layoutInflater.inflate(R.layout.row,null);
            viewHolder = new ViewHolder(convertView);
            convertView.setTag(viewHolder);
        }else {
            viewHolder = (ViewHolder)convertView.getTag();
        }

        //普通の処理

        //レイアウトの取得と値のマッピング
        Member member = (Member) getItem(position);

        //cancel
        ImageLoader.ImageContainer imageContainer = (ImageLoader.ImageContainer)viewHolder.memberImage.getTag();
        if(imageContainer != null){
            imageContainer.cancelRequest();
        }

        //
        //viewHolder.memberImage.setImageBitmap(member.getImage());
        String url = member.getUrl();
        ImageLoader.ImageListener listener = ImageLoader.getImageListener(
                viewHolder.memberImage, R.drawable.ic_launcher, R.drawable.ic_launcher);
        
        imageLoader.get(url,listener);

        viewHolder.memberName.setText(member.getName());
        viewHolder.memberAge.setText(Integer.toString(member.getAge()));
        viewHolder.memberUrl.setText(member.getUrl());

        //
        return convertView;
    }

    //ViewHolder
    private static class ViewHolder{

        ImageView memberImage;
        TextView memberName;
        TextView memberAge;
        TextView memberUrl;

        public ViewHolder(View view){

            this.memberImage = (ImageView)view.findViewById(R.id.image);
            this.memberName = (TextView)view.findViewById(R.id.txtName);
            this.memberAge = (TextView)view.findViewById(R.id.txtAge);
            this.memberUrl = (TextView)view.findViewById(R.id.txtUrl);

        }
    }
}
```
Cacheのコード。
[レピカ開発者のブログ](http://www.repica.jp/staffblog/tech/2013/12/27/1400/)のコードをそのまま利用させていただきました。


```MyLruCache.java
public class MyLruCache implements ImageLoader.ImageCache{

    private LruCache<String, Bitmap> mMemoryCache;

    public MyLruCache() {
        int maxSize = 10 * 1024 * 1024;
        mMemoryCache = new LruCache<String, Bitmap>(maxSize) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getRowBytes() * value.getHeight();
            }
        };
    }

    @Override
    public Bitmap getBitmap(String url) {
        return mMemoryCache.get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        mMemoryCache.put(url, bitmap);
    }
}
```

以上。普段LL言語ばかり使ってる人間には重い。