동적이지만 정사각형 레이아웃을 수행하는 간단한 방법 나는 LinearLayouts모두 정사각형이 되길 원하지만 동적으로 크기가

나는 GridView본질적으로 많은 뷰를 표시 하기 위해 사용하고 있습니다 LinearLayouts. 나는 LinearLayouts모두 정사각형이 되길 원하지만 동적으로 크기가 조정되기를 원합니다 LinearLayouts. xml레이아웃을 통해이 작업을 수행하는 방법이 있습니까? 아니면 프로그래밍 방식으로 높이와 너비를 설정해야합니까?



답변

정사각형 GridView항목에 대한 깔끔한 솔루션은 다음 과 같이 확장 RelativeLayout하거나 LinearLayout재정의하는 onMeasure것입니다.

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


답변

답변이 늦어 질 수 있지만 그래도 새로운 방문객에게 도움이 될 것입니다.

Android Studio 2.3에 도입 된 새로운 ConstraintLayout을 사용하면 이제 반응 형 레이아웃을 매우 쉽게 빌드 할 수 있습니다.

부모 ConstraintLayout에서 자식 뷰 / 레이아웃을 동적으로 정사각형으로 만들려면이 속성을 추가합니다.

app:layout_constraintDimensionRatio="w,1:1"

w는 너비 방향 제약을 지정하는 것이며 1 : 1 비율은 정사각형 레이아웃을 보장합니다.


답변

xml에는 width 및 height 속성을 연결할 수있는 것이 없습니다. 아마도 가장 쉬운 방법은 하위 클래스를 LinearLayout만들고 재정의하는 것입니다.onMeasure

@Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);
    int size = width > height ? height : width;
    setMeasuredDimension(size, size);
}

나는 이것을 사용하여 항상 이전에 정사각형 인 뷰를 만들었습니다. 여전히 LinearLayout.

이를 수행하는 데 도움이되는 추가 정보 :
http://developer.android.com/guide/topics/ui/custom-components.html

http://developer.android.com/reference/android/view/View.MeasureSpec.html


답변

나는 이렇게했다 :

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    int size;
    if(widthMode == MeasureSpec.EXACTLY && widthSize > 0){
        size = widthSize;
    }
    else if(heightMode == MeasureSpec.EXACTLY && heightSize > 0){
        size = heightSize;
    }
    else{
        size = widthSize < heightSize ? widthSize : heightSize;
    }

    int finalMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
    super.onMeasure(finalMeasureSpec, finalMeasureSpec);
}

이 구현에서는 너비와 높이 사이의 크기가 더 낮다고 가정하여 레이아웃이 정사각형이됩니다. 또한 LinearLayout 내부에서 가중치를 사용하는 것과 같이 동적 값으로 설정할 수도 있습니다.


답변

아주 간단한 방법으로 할 수 있습니다 super.onMeasure(). 두 번만 전화하면 됩니다.

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int width = getMeasuredWidth();
    int height = getMeasuredHeight();
    int squareLen = Math.min(width, height);

    super.onMeasure(
        MeasureSpec.makeMeasureSpec(squareLen, MeasureSpec.EXACTLY),
        MeasureSpec.makeMeasureSpec(squareLen, MeasureSpec.EXACTLY));
}

super.onMeasure()두 번 호출 하면 그리기 프로세스 측면에서 효율성이 떨어지지 만 다른 답변으로 인해 발생할 수있는 레이아웃 문제를 해결하는 간단한 방법입니다.


답변

다음과 같이 간단합니다.

public class SquareRelativeLayout extends RelativeLayout {

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

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

    public SquareRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        if (widthMeasureSpec < heightMeasureSpec)
            super.onMeasure(widthMeasureSpec, widthMeasureSpec);
        else
            super.onMeasure(heightMeasureSpec, heightMeasureSpec);
    }
}


답변

다음은보기 또는보기 그룹으로 설정할 수있는 모든 레이아웃 매개 변수에 대해 작동하는 솔루션입니다.

    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);
    int widthDesc = MeasureSpec.getMode(widthMeasureSpec);
    int heightDesc = MeasureSpec.getMode(heightMeasureSpec);
    int size = 0;
    if (widthDesc == MeasureSpec.UNSPECIFIED
            && heightDesc == MeasureSpec.UNSPECIFIED) {
        size = DP(defaultSize); // Use your own default size, in our case
                                // it's 125dp
    } else if ((widthDesc == MeasureSpec.UNSPECIFIED || heightDesc == MeasureSpec.UNSPECIFIED)
            && !(widthDesc == MeasureSpec.UNSPECIFIED && heightDesc == MeasureSpec.UNSPECIFIED)) {
                    //Only one of the dimensions has been specified so we choose the dimension that has a value (in the case of unspecified, the value assigned is 0)
        size = width > height ? width : height;
    } else {
                    //In all other cases both dimensions have been specified so we choose the smaller of the two
        size = width > height ? height : width;
    }
    setMeasuredDimension(size, size);

건배