IT story

Android : 뷰에 maxHeight가없는 이유는 무엇입니까?

hot-time 2020. 5. 29. 23:44
반응형

Android : 뷰에 maxHeight가없는 이유는 무엇입니까?


보기에는minHeight 있지만 어떻게 든 부족합니다 maxHeight.

내가 달성하려는 것은 일부 항목 (보기)을 채우는 것입니다 ScrollView. 1..3 항목이 있으면 직접 표시하고 싶습니다. 의미는 ScrollView높이가 1, 2 또는 3 항목임을 의미합니다 .

4 개 이상의 항목이 있으면 ScrollView확장을 중지 하고 (그래서 a maxHeight) 스크롤 제공을 시작하려고합니다.

그러나 불행히도를 설정하는 방법은 없습니다 maxHeight. 따라서 아마도 1..3 항목이있을 때 ScrollView프로그래밍 방식으로 WRAP_CONTENT높이를 설정하고 3*sizeOf(View)4 개 이상의 항목이있을 때 높이를 설정해야 합니다.

아무도 maxHeight이미 제공 되지 않은 이유가 무엇인지 설명 할 수 있습니까 minHeight?

(BTW : 일부 견해 ImageViewmaxHeight구현 된 것과 같습니다 .)


이 솔루션 중 어느 것도 wrap_content로 설정했지만 maxHeight를 갖는 ScrollView 인 특정 지점에서 작동하지 않아 특정 지점 후에 확장이 중지되고 스크롤이 시작됩니다. 단순히 ScrollView에서 onMeasure 메소드를 무시합니다.

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(300, MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

이것은 모든 상황에서 작동하지는 않지만 레이아웃에 필요한 결과를 제공합니다. 또한 madhu의 의견도 다루고 있습니다.

scrollview 아래에 일부 레이아웃이 있으면이 트릭이 작동하지 않습니다-madhu Mar 5 at 4:36


를 만들려면 ScrollView또는 ListView의 maxHeight 당신은 당신이의 maxHeight이 원하는 무엇의 높이 주위에 투명있는 LinearLayout을 작성해야합니다. 그런 다음 ScrollView 's Height를로 설정하십시오 wrap_content. 높이가 부모 LinearLayout과 같아 질 때까지 커지는 ScrollView를 만듭니다.


이것은 xml에서 사용자 정의 할 수있게 해주었습니다.

MaxHeightScrollView.java :

public class MaxHeightScrollView extends ScrollView {

private int maxHeight;
private final int defaultHeight = 200;

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

public MaxHeightScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
    if (!isInEditMode()) {
        init(context, attrs);
    }
}

public MaxHeightScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    if (!isInEditMode()) {
        init(context, attrs);
    }
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public MaxHeightScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    if (!isInEditMode()) {
        init(context, attrs);
    }
}

private void init(Context context, AttributeSet attrs) {
    if (attrs != null) {
        TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.MaxHeightScrollView);
        //200 is a defualt value
        maxHeight = styledAttrs.getDimensionPixelSize(R.styleable.MaxHeightScrollView_maxHeight, defaultHeight);

        styledAttrs.recycle();
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}

attr.xml

<declare-styleable name="MaxHeightScrollView">
        <attr name="maxHeight" format="dimension" />
    </declare-styleable>

레이아웃 예

<blah.blah.MaxHeightScrollView android:layout_weight="1"
                app:maxHeight="90dp"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content">
                <EditText android:id="@+id/commentField"
                    android:hint="Say Something"
                    android:background="#FFFFFF"
                    android:paddingLeft="8dp"
                    android:paddingRight="8dp"
                    android:gravity="center_vertical"
                    android:maxLines="500"
                    android:minHeight="36dp"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content" />
            </blah.blah.MaxHeightScrollView>

(이것은 질문에 직접 대답하지 않지만 maxHeight 기능을 찾는 다른 사람들에게 도움이 될 수 있음을 알고 있습니다)

ConstraintLayout은 다음을 통해 자녀에게 최대 높이를 제공합니다

app:layout_constraintHeight_max="300dp"
app:layout_constrainedHeight="true" 

또는

app:layout_constraintWidth_max="300dp"
app:layout_constrainedWidth="true" 

샘플 사용법은 여기 입니다.


가능한 경우 whizzle의 대답에 대해 언급했지만 Android N의 다중 창 모드 에서이 문제를 해결하려면 코드를 약간 변경해야한다는 점에 유의하는 것이 유용하다고 생각했습니다.

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if(MeasureSpec.getSize(heightMeasureSpec) > maxHeight) {
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

따라서 레이아웃의 크기를 최대 높이보다 작게 할 수 있지만 최대 높이보다 커지는 것을 방지 할 수 있습니다. 나는이 오버라이드 (override)하는 레이아웃 클래스를 사용 RelativeLayout하고이 날은 함께 사용자 지정 대화 상자를 만들 수 ScrollView의 자식으로 MaxHeightRelativeLayout화면의 전체 높이를 확장하지 않습니다 또한 안드로이드를위한 멀티 윈도우에서 가장 작은 과부의 크기에 맞도록 축소 엔.


maxHeight를 설정할 방법이 없습니다. 그러나 높이를 설정할 수 있습니다.

그렇게하려면 scrollView의 각 항목의 높이를 감지해야합니다. 그런 다음 scrollView 높이를 numberOfItens * heightOfItem으로 설정하십시오.

항목의 높이를 발견하려면 다음을 수행하십시오.

View item = adapter.getView(0, null, scrollView);
item.measure(0, 0);
int heightOfItem = item.getMeasuredHeight();

높이를 설정하려면 다음을 수행하십시오.

// if the scrollView already has a layoutParams:
scrollView.getLayoutParams().height = heightOfItem * numberOfItens;
// or
// if the layoutParams is null, then create a new one.
scrollView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, heightOfItem * numberOfItens));

MaxHeightScrollView맞춤보기

public class MaxHeightScrollView extends ScrollView {
    private int maxHeight;

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

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

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

    private void init(Context context, AttributeSet attrs) {
        TypedArray styledAttrs =
                context.obtainStyledAttributes(attrs, R.styleable.MaxHeightScrollView);
        try {
            maxHeight = styledAttrs.getDimensionPixelSize(R.styleable.MaxHeightScrollView_mhs_maxHeight, 0);
        } finally {
            styledAttrs.recycle();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (maxHeight > 0) {
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

style.xml

<declare-styleable name="MaxHeightScrollView">
    <attr name="mhs_maxHeight" format="dimension" />
</declare-styleable>

사용

<....MaxHeightScrollView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:mhs_maxHeight="100dp"
    >

    ...

</....MaxHeightScrollView>

layout_weight 값을 사용해 보셨습니까 ? 하나를 0보다 큰 값으로 설정하면 사용 가능한 남은 공간으로 해당보기가 확장됩니다.

여러 뷰를 늘려야하는 경우 값이 그 사이의 가중치가됩니다.

따라서 두 개의 뷰가 모두 layout_weight 값으로 1로 설정되어 있으면 공간을 채우기 위해 확장되지만 둘 다 동일한 양의 공간으로 확장됩니다. 이 중 하나를 2 값으로 설정하면 다른보기보다 두 배 늘어납니다.

Some more info here listed under Linear Layout.


As we know devices running android can have different screen sizes. As we further know views should adjust dynamically and become the space which is appropriate.

If you set a max height you maybe force the view not to get enough space or take to less space. I know that sometimes it seems to be practically to set a max height. But if the resolution will ever change dramatically, and it will!, then the view, which has a max height, will look not appropriate.

i think there is no proper way to exactly do the layout you want. i would recommend you to think over your layout using layout managers and relative mechanisms. i don't know what you're trying to achieve but it sounds a little strange for me that a list should only show three items and then the user has to scroll.

btw. minHeight is not guaranteed (and maybe shouldn't exist either). it can have some benefit to force items to be visible while other relative items get smaller.


If anyone is considering using exact value for LayoutParams e.g.

setLayoutParams(new LayoutParams(Y, X );

Do remember to take into account the density of the device display otherwise you might get very odd behaviour on different devices. E.g:

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics d = new DisplayMetrics();
display.getMetrics(d);
setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, (int)(50*d.density) ));

Wrap your ScrollView around your a plainLinearLayout with layout_height="max_height", this will do a perfect job. In fact, I have this code in production from last 5 years with zero issues.

<LinearLayout
        android:id="@+id/subsParent"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:gravity="bottom|center_horizontal"
        android:orientation="vertical">

        <ScrollView
            android:id="@+id/subsScroll"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:layout_marginEnd="15dp"
            android:layout_marginStart="15dp">

            <TextView
                android:id="@+id/subsTv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/longText"
                android:visibility="visible" />

        </ScrollView>
    </LinearLayout>

i think u can set the heiht at runtime for 1 item just scrollView.setHeight(200px), for 2 items scrollView.setheight(400px) for 3 or more scrollView.setHeight(600px)


First get the item height in pixels

View rowItem = adapter.getView(0, null, scrollView);   
rowItem.measure(0, 0);    
int heightOfItem = rowItem.getMeasuredHeight();

then simply

Display display = getWindowManager().getDefaultDisplay();    
DisplayMetrics displayMetrics = new DisplayMetrics();    
display.getMetrics(displayMetrics);    
scrollView.getLayoutParams().height = (int)((heightOfItem * 3)*displayMetrics .density);

if you guys want to make a non-overflow scrollview or listview, just but it on a RelativeLayout with a topview and bottomview on top and bottom for it:

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_above="@+id/topview"
    android:layout_below="@+id/bottomview" >

I have an answer here:

https://stackoverflow.com/a/29178364/1148784

Just create a new class extending ScrollView and override it's onMeasure method.

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (maxHeight > 0){
            int hSize = MeasureSpec.getSize(heightMeasureSpec);
            int hMode = MeasureSpec.getMode(heightMeasureSpec);

            switch (hMode){
                case MeasureSpec.AT_MOST:
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.min(hSize, maxHeight), MeasureSpec.AT_MOST);
                    break;
                case MeasureSpec.UNSPECIFIED:
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
                    break;
                case MeasureSpec.EXACTLY:
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.min(hSize, maxHeight), MeasureSpec.EXACTLY);
                    break;
            }
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

참고URL : https://stackoverflow.com/questions/4054567/android-why-is-there-no-maxheight-for-a-view

반응형