Fit GridView exactly into Screen

时间:2016-08-31 18:29:55

标签: android gridview

I have been reading a few posts on this but can't figure out the problem. I am trying to fit a GridView with 6 tiles in 2 columns EXACTLY on the screen of the device such that no scrolling is necessary. This how it looks like:

Desired screen

So I try to calculate the height of each tile as screen size minus action bar height minus vertical spaces. This is my code to calculate the height of a tile:

public static int getTileHeight(int numOfRows, int verticalSpacing, Context context) {
    TypedValue tv = new TypedValue();
    int actionBarHeight = 0;
    if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
        actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
    }

    DisplayMetrics displaymetrics = new DisplayMetrics();
    ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    int height = displaymetrics.heightPixels;

    int px = Math.round((numOfRows - 1) * verticalSpacing * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
    return ((height - actionBarHeight - px) / numOfRows);
}

The vertical spacing is retrieved by

  gridView.getVerticalSpacing()

Then in my GridViewAdapter, I set the height of each tile in getView:

  picture.getLayoutParams().height = getTileHeight(...);

where picture is an ImageView with a picture in it.

However, the height of the GridView is always a tiny little bit too big for the screen. I cannot achieve a perfect match into the screen height. Any ideas what I am missing?

2 个答案:

答案 0 :(得分:0)

can you try this out ? It seems you have to double the action bar size.

EDITED:

public static int getTileHeight(int numOfRows, int verticalSpacing, Context context) {
    TypedValue tv = new TypedValue();
    int actionBarHeight = 0;
    if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
        actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
    }
    int statusBarHeight = 0;
    int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        statusBarHeight = context.getResources().getDimensionPixelSize(resourceId);
    }

    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    int height = size.y - actionBarHeight - statusBarHeight; // removed *2 for action bar height and added status bar height
    int totalSpacing = verticalSpacing*(numOfRows+1);

    return ((height - totalSpacing) / numOfRows); 
}

This code will give you height if you want top and bottom spacing. I believe using numberOfRows-1 in total spacing will give yout the tile height without top and bottom spacing

答案 1 :(得分:0)

感谢Karakuri的评论,我将GridView更改为LinearLayout,因为我总是有6个图块。我现在正在使用这个xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight=".333">
    <include android:id="@+id/burnt_tile"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight=".5"
        layout="@layout/tile"/>
    <include android:id="@+id/meal_tile"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight=".5"
        layout="@layout/tile"/>
</LinearLayout>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight=".333">
    <include android:id="@+id/peace_tile"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight=".5"
        layout="@layout/tile"/>
    <include android:id="@+id/sin_tile"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight=".5"
        layout="@layout/tile"/>
</LinearLayout>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight=".333">
    <include android:id="@+id/trespass_tile"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight=".5"
        layout="@layout/tile"/>
    <include android:id="@+id/overview_tile"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight=".5"
        layout="@layout/tile"/>
</LinearLayout>
</LinearLayout>

这会按照我想要的方式对齐所有瓷砖! @Karakuri:谢谢!