Superdry Memorandom :-p

旧「superdry memorandum :-D」です

GridViewについてあんまり見かけないので訳してみた

元サイトはこちら→http://developer.android.com/intl/ja/resources/tutorials/views/hello-gridview.html

GridViewはスクロール可能な二次元の格子状に項目を表示するViewGroupです。 格子に表示するアイテムは、ListAdapterを使用することで自動的にレイアウトに挿入されます。以下のチュートリアルでは、画像のサムネイルのGrid上にならべ、画像が選択すると画像の位置をToastで表示するものを作成していきます。

1.HelloGridViewという新しいプロジェクトを作成。
2.res/drawableの下に表示したい画像をコピー。
3.res/layout/main.xmlファイルを開いて、以下を挿入。

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/gridview"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:columnWidth="90dp"
    android:numColumns="auto_fit"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="10dp"
    android:stretchMode="columnWidth"
    android:gravity="center"
/>

このGridViewは画面いっぱいに表示されます。使用可能なプロパティに関する詳しい情報に関しては、GridViewのリファレンス参照のこと。
4.HelloGridView.javaを作成しonCreate()メソッドの中に以下のコードを挿入

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

    GridView gridview = (GridView) findViewById(R.id.gridview);
    gridview.setAdapter(new ImageAdapter(this));

    gridview.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
            Toast.makeText(HelloGridView.this, "" + position, Toast.LENGTH_SHORT).show();
        }
    });
}

ContentViewにmain.xmlをセットしたあと、GridViewのレイアウトはfindViewById(int)で指定したidから取得されます。setAdapter()メソッドで、格子状にすべての画像を表示するカスタムAdapter (ImageAdapter)をセットします。ImageAdapterは次の手順で作成します。

格子状の画像の一つをクリックしたときの動作は、インスタンス化したAdapterView.OnItemClickListenerのsetOnItemClickListener()メソッドへ渡されます。このインスタンスは、コールバックメソッドonItemClick()に、選択した画像のインデックス位置をToastで表示するよう定義します。(実際には、位置はフルサイズの画像を取得するのによく使われます)

5.BaseAdapterを継承したImageAdapterクラスを作成

public class ImageAdapter extends BaseAdapter {
    private Context mContext;
    
public ImageAdapter(Context c) {
        mContext = c;
    }
    public int getCount() {
        return mThumbIds.length;
    }
    public Object getItem(int position) {
        return null;
    }
    public long getItemId(int position) {
        return 0;
    }

    // create a new ImageView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) {  // if it's not recycled, initialize some attributes
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(8, 8, 8, 8);
        } else {
            imageView = (ImageView) convertView;
        }
        imageView.setImageResource(mThumbIds[position]);
        return imageView;
    }

    // references to our images
    private Integer[] mThumbIds = {
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
            R.drawable.sample_6, R.drawable.sample_7,
            R.drawable.sample_0, R.drawable.sample_1,
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
            R.drawable.sample_6, R.drawable.sample_7,
            R.drawable.sample_0, R.drawable.sample_1,
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
            R.drawable.sample_6, R.drawable.sample_7
    };
}

はじめにBaseAdapterから継承した必要なメソッドを実装します。コンストラクタとgetCount()は見てのとおり。普通、getItem(int)はアダプターの特定の位置の実際のオブジェクトを返すよう実装しますが、今回の例では無視してnullを返してます。同様にgetItemId(int)もアイテムのrow idを返すよう実装しますが、ここでは必要でないので0を返します。

最初に必要なメソッドはgetView()です。このメソッドはImageAdapterへ追加された画像ごとのViewを作成します。これがコールされたとき、このViewは通常、既に生成されたオブジェクトであることが多いので(少なくとも1回はコールされていることが多い)、まずオブジェクトがnullかどうかのチェックをします。もしnullの場合、ImageViewをインスタンス化し、画像表示のためのプロパティをセットします。

  • setLayoutParams(ViewGroup.LayoutParams)はViewの高さと幅のセットします。この設定のとおり、画像は適当にリサイズ&切り取りされます。
  • setScaleType(ImageView.ScaleType)は、(必要な場合)中央を中心に画像が切り取られる設定です。もし画像が異なるアスペクト比の場合、
  • setPadding(int、int、int、int)は4方向からのPaddingを定義します。Paddingが少ないと、もし画像が異なるアスペクト比の場合、特にImageViewから得られる縦横に合わない場合にはより多く切り取られることいなります。

getView()に渡されたViewがnullでないなら、ローカルのImageViewは再利用されるViewオブジェクトとして初期化されます。getView()メソッドの最後に位置を示すintegerを、ImageViewの画像リソースを設定しているmThumbIds配列にセットし、画像を選択するのに使います。

以降は、描画リソースをmThumbIds配列に定義しています。

6.アプリケーションを実行

こんな感じに表示されます

プロパティをいじってみて、GridViewとImageViewのふるまいをいろいろ体験してください。例えば、setLayoutParams(ViewGroup.LayoutParams)の代わりにsetAdjustViewBounds(boolean)を使ってみるとか。