[android] GridView 항목을 정사각형으로 만들기

내 아이템을 GridView사각형으로 만들고 싶습니다 . 2 개의 열이 있으며 항목 너비는 fill_parent(예 : 가능한 한 많은 가로 공간을 차지합니다. 항목은 사용자 정의보기입니다.

항목 높이를 가변 너비와 동일하게 만드는 방법은 무엇입니까?



답변

GridView 열을 늘릴 때 더 간단한 솔루션이 있습니다. GridView 항목 레이아웃의 onMeasure를 다음으로 재정의하십시오.

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}


답변

또는 뷰를 확장하려면 다음과 같이 아주 간단한 작업을 수행하십시오.

public class SquareImageView extends ImageView
{

    public SquareImageView(final Context context)
    {
        super(context);
    }

    public SquareImageView(final Context context, final AttributeSet attrs)
    {
        super(context, attrs);
    }

    public SquareImageView(final Context context, final AttributeSet attrs, final int defStyle)
    {
        super(context, attrs, defStyle);
    }


    @Override
    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec)
    {
        final int width = getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
        setMeasuredDimension(width, width);
    }

    @Override
    protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh)
    {
        super.onSizeChanged(w, w, oldw, oldh);
    }
}

super.onMeasure()필요하지 않다는 점 은 주목할 가치가 있습니다. onMeasured요구 사항은 전화해야한다는 것 setMeasuredDimension입니다.


답변

현재 위젯에서 이것이 가능한지 잘 모르겠습니다. 가장 좋은 방법은 사용자 정의보기를 사용자 정의 “SquareView”에 넣는 것입니다. 이 뷰는 자식 뷰를 1 개만 포함 할 수 있으며 onLayout 메서드가 호출 될 때 높이를 너비와 동일하게 만들 수 있습니다.

그렇게하려고 한 적은 없지만 너무 어렵지 않을 것 같아요. 대안 (그리고 약간 더 쉬울 수도 있음) 솔루션은 사용자 정의보기의 루트 레이아웃을 하위 클래스로 만들고 (예 : LinearLayout 인 경우 SquareLinearLayout을 만들어) 대신 컨테이너로 사용하는 것입니다.

편집 : 나를 위해 작동하는 기본 구현은 다음과 같습니다.

package com.mantano.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

public class SquareView extends ViewGroup {

    public SquareView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onLayout(boolean changed, int l, int u, int r, int d) {
        getChildAt(0).layout(0, 0, r-l, d-u); // Layout with max size
    }

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

        View child = getChildAt(0);
        child.measure(widthMeasureSpec, widthMeasureSpec);
        int width = resolveSize(child.getMeasuredWidth(), widthMeasureSpec);
        child.measure(width, width); // 2nd pass with the correct size
        setMeasuredDimension(width, width);
    }
}

고유 한 자식을 갖도록 설계되었지만 단순성을 위해 모든 검사를 무시했습니다. 기본 아이디어는 GridView에서 설정 한 너비 / 높이 매개 변수로 자식을 측정 한 다음 (내 경우에는 너비를 계산하기 위해 numColumns = 4 사용) 높이 = 너비로 최종 치수로 두 번째 패스를 수행하는 것입니다. .. 레이아웃은 단순한 레이아웃으로, (0, 0)에 고유 한 자식을 원하는 크기 (오른쪽-왼쪽, 아래쪽-위)로 레이아웃합니다.

다음은 GridView 항목에 사용되는 XML입니다.

<?xml version="1.0" encoding="utf-8"?>
<com.mantano.widget.SquareView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="wrap_content">

    <LinearLayout android:id="@+id/item" android:layout_width="fill_parent"
        android:layout_height="fill_parent" android:orientation="horizontal"
        android:gravity="center">

        <TextView android:id="@+id/text" android:layout_width="fill_parent"
            android:layout_height="wrap_content" android:text="Hello world" />
    </LinearLayout>
</com.mantano.widget.SquareView>

모든 중력 가능성, 여백 등을 관리하기 위해 SquareView 내부에 LinearLayout을 사용했습니다.

이 위젯이 방향 및 치수 변경에 얼마나 잘 (또는 나쁘게) 반응하는지 잘 모르겠지만 제대로 작동하는 것 같습니다.


답변

그리드 항목 사각형을 얻는 것은 상당히 쉽습니다.

그리드 어댑터의 “GetView”메소드에서 다음을 수행하십시오.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    GridView grid = (GridView)parent;
    int size = grid.getRequestedColumnWidth();

    TextView text = new TextView(getContext());
    text.setLayoutParams(new GridView.LayoutParams(size, size));

    // Whatever else you need to set on your view

    return text;
}


답변

이것이 최선의 방법인지는 모르겠지만 사용자 정의보기를 사용하여 onSizeChanged를 재정의하도록 수행합니다.

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);

    if (getLayoutParams() != null && w != h) {
        getLayoutParams().height = w;
        setLayoutParams(getLayoutParams());
    }
}

LinearLayout 및 GridView 내에서이 사용자 지정보기를 사용하고 둘 다 사각형으로 표시됩니다!


답변

이것은 나를 위해 일했습니다!

당신이 나와 같고 minSdk가 16보다 낮기 때문에 getRequestedColumnWidth ()를 사용할 수 없다면이 옵션을 제안합니다.

  1. 조각에서 :

    DisplayMetrics dm = new DisplayMetrics();
    getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
    int size = dm.widthPixels / nbColumns;
    CustomAdapter adapter = new CustomAdapter(list, size, getActivity());

  2. 어댑터에서 (getView (int position, View convertView, ViewGroup parent))

    v.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, size));

  3. fragment.xml :

    <GridView
    android:id="@+id/gridView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:horizontalSpacing="3dp"
    android:verticalSpacing="3dp"
    android:numColumns="4"
    android:stretchMode="columnWidth" />

  4. custom_item.xml : (예)

    <ImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/picture"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scaleType="centerCrop" />

누군가를 도울 수 있기를 바랍니다!


답변

xml에서 정적 열 수를 설정하면보기의 너비를 열 수로 나눌 수 있습니다.

사용하는 경우 auto_fit열 수를 얻는 것이 약간 까다로울 것입니다 (getColumnCount () 메서드가 없습니다). btw 질문은 어떻게 든 도움이 될 것입니다.

이것은 getView(...)고정 된 수의 열이있는 어댑터 메서드에 사용하는 코드 입니다.

    item_side = mFragment.holder.grid.getWidth() / N_COL;
    v.getLayoutParams().height = item_side;
    v.getLayoutParams().width = item_side;