[Android] GridView の横幅を wrap_content に従わせる
GridView の中のアイテムを整列させるルールとして stretchMode を指定するのですが、アイテム同士が隙間なく並んだ状態で GridView 全体を画面中央に寄せるという要望は、既存の GridView では思ったように実装出来ませんでした。
以下の実装をしました。
- GridView に
strechMode="none"
- GridView の横幅に
wrap_cotent"
- GridView の親ビューに
gravity="center"
- GridView の親ビュー横幅に
match_parent
ですが、何故か GridView には wrap_content
が効かずに、match_parent
のような振る舞いになってしまう。
どうやら自身の縦幅・横幅を決定する onMeasure()
で、計算するしかないみたいです。その実装をメモしておきます。
GridView の横幅を onMeasure() で計算する
FixedGridView という GridView のサブクラスを作り、onMeasure()
で、横幅と縦幅を計算しています。
計算結果を setMeasuredDimension()
にセットすれば OK です。
カラムサイズを決め打ちしていますが、API Level 16 以上では、getColumnWidth()
が使えます:
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.GridView;
public class FixedGridView extends GridView {
private static final int COLUMN_SIZE = 150;
public FixedGridView(Context context) {
super(context);
}
public FixedGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FixedGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int num = getNumColumns();
float density = getResources().getDisplayMetrics().density;
int px = Math.round(COLUMN_SIZE * density);
int width = px * num; // px * カラム数
int height = px * (int)Math.ceil((float)getAdapter().getCount()/(float)num); // px * 行数
setMeasuredDimension(width, height);
}
}
後は、アイテム同士が隙間なく並んだ状態で GridView 全体を画面中央に寄せるレイアウトを記述すれば OK です:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp"
android:gravity="center">
<FixedGridView
android:id="@+id/gridview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:columnWidth="150dp"
android:numColumns="auto_fit"
android:stretchMode="none"/>
</LinearLayout>