38
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

セクションヘッダー付きの GridView で、かつ「もっと読む」とか「PullToRefresh」もしたい

Last updated at Posted at 2014-02-20

ListView を用いて、ListView の中に GridView をねじ込んで実装する。

+--------------------+
|   Header content   |
+------+------+------+
| Cell | Cell | Cell |
+------+------+------+
| Cell | Cell | Cell |
+------+------+------+
| Cell | Cell | Cell |
+------+------+------+
|   Header content   |
+------+------+------+
| Cell | Cell | Cell |
+------+------+------+
| Cell | Cell | Cell |
+------+------+------+
| Cell | Cell | Cell |
+------+------+------+
...

データ構造

一行分のデータを表すデータ構造は、

  • セクションヘッダーとして取り扱う為のデータ
  • GridView に表示するリストのデータ

このデータ構造を保持するコレクションを作って、ListView のアダプターに渡していくスタイル。

public class SectionData {
    private String mSectionName;
    private List<String> mImages;
}

レイアウト

リストの一行ごとに、GridView をねじ込んでいくスタイル。こうすれば、一行ごとのレイアウトに、GridView のセクションヘッダーの役割を果たすレイアウトを含めることが出来る。

このとき、スクロールのハンドリングが ListView と GridView で二重化してしまうので、GridView のスクロールをしないよう、高さを中身の数に合わせて固定化する(参考リンク)。

// StackOverFlow の回答の実装
public class NonScrollableGridView extends GridView {
    public NonScrollableGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // Do not use the highest two bits of Integer.MAX_VALUE because they are
        // reserved for the MeasureSpec mode
        int heightSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightSpec);
        getLayoutParams().height = getMeasuredHeight();
    }
}

アダプター

ListView 用のアダプターと、GridView 用のアダプターを用意する。

ListView 用のアダプターの ListAdapter#getView(int, View, ViewGroup)では、GridView の初期化と GridView 用のアダプターの初期化および設定をする。

public class SectionListAdapter extends ArrayAdapter<SectionData> {
    public SectionListAdapter(Context context, List<SectionData> objects) {
        super(context, R.layout.list_item_layout, R.id.label_section_title, objects);
    }

    @Nullable
    @Override
    public View getView(int position, View convertView, ViewGroup group) {
        View row = super.getView(position, convertView, group);

        SectionData data = getItem(position);

        TextView sectionName = (TextView) row.findViewById(R.id.label_section_name);
        sectionName.setText(data.getSectionName());

        GridView grid = (GridView) row.findViewById(R.id.grid);
        SectionGridAdapter adapter = new SectionGridAdapter(getContext(), data.getImageUrls());
        grid.setAdapter(adapter);

        return row;
    }
}

GridView 用のアダプターは、いつもどおりセルのレイアウトを生成するコードを書く。

public class SectionGridAdapter extends ArrayAdapter<String> {
    public SectionGridAdapter(Context context, List<String> objects) {
        super(context, R.layout.grid_item, R.id.label_grid, objects);
    }

    @Nullable
    @Override
    public View getView(int position, View convertView, ViewGroup group) {
        View cell = super.getView(position, convertView, group);

        ImageView image = (ImageView) cell.findViewById(R.id.image_cell);
        // Picasso 使うなら
        Picasso.with(getContext()).load(getItem(position)).into(image);

        return cell;
    }
}

もっと読むとか PullToRefresh とか

ListView なので、もっと読むは FooterView が使える。

PullToRefresh も、このライブラリであれば、ListView を PullToRefreshListView に置き換えて使うことができる。

簡単!

38
41
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
38
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?