programing tip

그리드 뷰 높이가 잘림

itbloger 2020. 7. 13. 21:40
반응형

그리드 뷰 높이가 잘림


gridview 안에 8 개의 항목을 표시하려고합니다. 안타깝게도 그리드 뷰 높이는 항상 너무 작아서 첫 번째 행과 두 번째 행의 일부만 표시합니다.

설정 android:layout_height="300dp"하면 작동합니다. wrap_ contentfill_parent분명히 아닙니다.

내 격자보기 :

<GridView
    android:id="@+id/myId"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:horizontalSpacing="2dp"
    android:isScrollContainer="false"
    android:numColumns="4"
    android:stretchMode="columnWidth"
    android:verticalSpacing="20dp" />

내 아이템 리소스 :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:minHeight="?android:attr/listPreferredItemHeight" >

    <ImageView
        android:id="@+id/appItemIcon"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:src="@android:drawable/ic_dialog_info"
        android:scaleType="center" />      

    <TextView
        android:id="@+id/appItemText"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="My long application name"
        android:gravity="center_horizontal"
        android:textAppearance="?android:attr/textAppearanceSmall" />

</LinearLayout>

이 문제는 수직 공간 부족과 관련이없는 것 같습니다.

어떡해 ?


(너무 많은) 연구 후, 나는 Neil Traft의 훌륭한 답변을 발견했습니다 .

그의 작품을 적응시키는 GridView것은 쉽지 않았다.

ExpandableHeightGridView.java :

package com.example;
public class ExpandableHeightGridView extends GridView
{

    boolean expanded = false;

    public ExpandableHeightGridView(Context context)
    {
        super(context);
    }

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

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

    public boolean isExpanded()
    {
        return expanded;
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        // HACK! TAKE THAT ANDROID!
        if (isExpanded())
        {
            // Calculate entire height by providing a very large height hint.
            // View.MEASURED_SIZE_MASK represents the largest height possible.
            int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
                    MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, expandSpec);

            ViewGroup.LayoutParams params = getLayoutParams();
            params.height = getMeasuredHeight();
        }
        else
        {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    public void setExpanded(boolean expanded)
    {
        this.expanded = expanded;
    }
}

다음과 같이 레이아웃에 포함하십시오.

<com.example.ExpandableHeightGridView
    android:id="@+id/myId"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:horizontalSpacing="2dp"
    android:isScrollContainer="false"
    android:numColumns="4"
    android:stretchMode="columnWidth"
    android:verticalSpacing="20dp" />

마지막으로 확장하도록 요청하면됩니다.

mAppsGrid = (ExpandableHeightGridView) findViewById(R.id.myId);
mAppsGrid.setExpanded(true);

After using the answer from @tacone and making sure it worked, I decided to try shorting down the code. This is my result. PS: It is the equivalent of having the boolean "expanded" in tacones answer always set to true.

public class StaticGridView extends GridView {

    public StaticGridView(Context context) {
        super(context);
    }

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

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

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK, MeasureSpec.AT_MOST));
        getLayoutParams().height = getMeasuredHeight();
    }
}

Another similar approach that worked for me, is to calculate the height for one row and then with static data (you may adapt it to paginate) you can calculate how many rows you have and resize the GridView height easily.

    private void resizeGridView(GridView gridView, int items, int columns) {
    ViewGroup.LayoutParams params = gridView.getLayoutParams();
    int oneRowHeight = gridView.getHeight();
    int rows = (int) (items / columns);
    params.height = oneRowHeight * rows;
    gridView.setLayoutParams(params);
}

Use this code after setting the adapter and when the GridView is drawn or you will get height = 0.

gridView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (!gridViewResized) {
                    gridViewResized = true;
                    resizeGridView(gridView, numItems, numColumns);
                }
            }
        });

Found tacones answer helpfull... so i ported it to C# (Xamarin)

public class ExpandableHeightGridView: GridView
{
    bool _isExpanded = false;

    public ExpandableHeightGridView(Context context) : base(context)
    {            
    }

    public ExpandableHeightGridView(Context context, IAttributeSet attrs) : base(context, attrs)
    {            
    }

    public ExpandableHeightGridView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
    {            
    }

    public bool IsExpanded
    {
        get { return _isExpanded; }

        set { _isExpanded = value;  }
    }

    protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        // HACK! TAKE THAT ANDROID!
        if (IsExpanded)
        {
            // Calculate entire height by providing a very large height hint.
            // View.MEASURED_SIZE_MASK represents the largest height possible.
            int expandSpec = MeasureSpec.MakeMeasureSpec( View.MeasuredSizeMask, MeasureSpecMode.AtMost);
            base.OnMeasure(widthMeasureSpec,expandSpec);                

            var layoutParameters = this.LayoutParameters;
            layoutParameters.Height = this.MeasuredHeight;
        }
        else
        {
            base.OnMeasure(widthMeasureSpec,heightMeasureSpec);    
        }
    }
}

Just calculate the height for AT_MOST and set to on measure. Here GridView Scroll will not work so. Need to use Vertical Scroll View explicitly.

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

     if (getLayoutParams().height == LayoutParams.WRAP_CONTENT) {

         heightSpec = MeasureSpec.makeMeasureSpec(
                        Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
     }
     else {
         // Any other height should be respected as is.
         heightSpec = heightMeasureSpec;
     }

     super.onMeasure(widthMeasureSpec, heightSpec);
 }

참고URL : https://stackoverflow.com/questions/8481844/gridview-height-gets-cut

반응형