2016年04月11日

ArrayAdapterのコンストラクタのResourceIDの役割

こんにちは、Androidエンジニアの外山です。

今回はAndroidのListViewなどにセットするArrayAdapterのコンストラクタで指定するResourceIDの役割について調べてみました。

ArrayAdapterのコンストラクタ

ArrayAdapterのコンストラクタは以下のようになっています。
public ArrayAdapter(Context context, @LayoutRes int resource, @IdRes int textViewResourceId,
            @NonNull List<T> objects) {
        mContext = context;
        mInflater = LayoutInflater.from(context);
        mResource = mDropDownResource = resource;
        mObjects = objects;
        mFieldId = textViewResourceId;
}

ResourceIDの使用箇所

mResourceとmFieldIdはgetViewでViewインスタンスを作成する時に使用されています。

mResourceはViewのレイアウトファイルを参照する際に、mFieldIdはレイアウトファイル内のTextViewを指定する際に使用されているようです(指定しなかった場合は生成したView自身をTextViewとして扱う)。

public View getView(int position, View convertView, ViewGroup parent) {
    return createViewFromResource(mInflater, position, convertView, parent, mResource);
}

private View createViewFromResource(LayoutInflater inflater, int position, View convertView,
        ViewGroup parent, int resource) {
    View view;
    TextView text;
    if (convertView == null) {
        view = inflater.inflate(resource, parent, false);
    } else {
        view = convertView;
    }
    try {
        if (mFieldId == 0) {
            //  If no custom field is assigned, assume the whole resource is a TextView
            text = (TextView) view;
        } else {
            //  Otherwise, find the TextView field within the layout
            text = (TextView) view.findViewById(mFieldId);
        }
    } catch (ClassCastException e) {
        Log.e("ArrayAdapter", "You must supply a resource ID for a TextView");
        throw new IllegalStateException(
                "ArrayAdapter requires the resource ID to be a TextView", e);
    }
    T item = getItem(position);
    if (item instanceof CharSequence) {
        text.setText((CharSequence)item);
    } else {
        text.setText(item.toString());
    }
    return view;
}

mDropDownResourceも同じような感じになっています。



まとめ

getViewをオーバーライドしてsuperメソッドを呼ばない場合は、引数で渡したResourceIDが使われることはないので`-1`など適当な値を渡しておけば大丈夫である。

リスト内のアイテムで一つのTextViewにのみ値をセットする場合はResourceIdを指定することでサブクラスを作成せずにAdapterを作成できるようだ。


RecyclerViewの登場によって使う機会が減ってきたListViewやGridViewですが簡単なリストを作成する際には手軽に使えていいですね。

posted by Seesaa京都スタッフ at 18:53| Comment(0) | Android | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: