A
A
Artem2013-03-20 14:40:46
Android
Artem, 2013-03-20 14:40:46

GridView with square cells?

I have a GridView in my application:

<GridView
    android:id="@+id/main_grid_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:numColumns="4" >
</GridView>

Each GridView cell contains an ImageView:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@+id/img"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:contentDescription="@string/img"
        android:scaleType="centerCrop" />

</RelativeLayout>

It is necessary that the picture fills all the free space of the cell and at the same time the cell would be square. How can this be achieved? In my case, the cells are always rectangular, stretched vertically.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
ara89, 2013-03-21
@ara89

if you need not a dashboard, but a grid with square images, create your own class, inherit from ImageView and override the onMeasure() method like this:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  int measuredWidth = getMeasuredWidth();
  setMeasuredDimension(measuredWidth, measuredWidth);
}

P
palmut, 2013-03-20
@palmut

Hmm, I do not know how to pick up the file here. But maybe something like this would work?

public class DashboardLayout extends ViewGroup {
  private final static String TAG = DashboardLayout.class.getName();

  private final static int DEFAULT_COLUMNS = 3;

  private int columns;

  public DashboardLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DashboardLayout);

    try {
      setColumns(a.getInt(R.styleable.DashboardLayout_dashboardColumns, DEFAULT_COLUMNS));
    } finally {
      a.recycle();
    }
  }

  public DashboardLayout(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public DashboardLayout(Context context) {
    this(context, null);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    int totalChildWidth = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();

    int visibleCount = getVisibleCount();
    if (visibleCount > 0) {

      int childWidth = totalChildWidth / columns;
      int childHeight = childWidth;

      int childWidthSpec = MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY);
      int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY);

      for (int i = 0, N = getChildCount(); i < N; i++) {
        final View child = getChildAt(i);
        if (child.getVisibility() != View.GONE) {
          child.measure(childWidthSpec, childHeightSpec);
        }
      }
    }

    setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {

    int childLeft = l + getPaddingLeft();
    int childTop = t + getPaddingTop();

    for (int i = 0, N = getChildCount(); i < N; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != View.GONE) {
        child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(),
                childTop + child.getMeasuredHeight());

        childLeft += child.getMeasuredWidth();
        if (childLeft + getPaddingRight() >= r) {
          childLeft = l + getPaddingLeft();
          childTop += child.getMeasuredHeight();
        }
      }
    }

  }

  /***
   * Set number of columns. By default DashboardLayout uses 3 columns
   * 
   * @param value
   *            - number of columns
   */
  public void setColumns(int value) {
    if (value != columns) {
      columns = value;
      requestLayout();
    }
  }

  /***
   * Returns number of columns.
   * 
   * @return number of columns
   */
  public int getColumns() {
    return columns;
  }

  private int getVisibleCount() {
    int count = 0;
    for (int i = 0, N = getChildCount(); i < N; i++) {
      if (getChildAt(i).getVisibility() != GONE) count++;
    }

    return count;
  }

}


Still need to put in res/values/attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="DashboardLayout">
        <attr name="dashboardColumns" format="integer" />
    </declare-styleable>

</resources>

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question