ImageView-높이가 너비와 일치합니까?


166

이미지 뷰가 있습니다. 너비를 fill_parent로 설정하고 싶습니다. 높이가 너비가 무엇이든 되길 원합니다. 예를 들면 다음과 같습니다.

<ImageView
  android:layout_width="fill_parent"
  android:layout_height="whatever the width ends up being" />

내 자신의 뷰 클래스를 만들지 않고도 레이아웃 파일에서 이와 같은 것이 가능합니까?

감사


이 작업을 수행하는 방법을 알아 냈습니까? 종횡비가 동일하게 유지되기를 원한다고 가정합니다. 이 답변의 대부분은 이미지를 정사각형으로 원한다고 가정합니다.
Adam

@Joe Blow 그것은 매우 나쁜 방법입니다
Aggressor

답변:


170

업데이트 : 2017 년 9 월 14 일

아래 의견에 따르면 퍼센트 지원 라이브러리는 Android 지원 라이브러리 26.0.0부터 더 이상 사용되지 않습니다. 이것이 새로운 방법입니다.

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintDimensionRatio="1:1" />

</android.support.constraint.ConstraintLayout>

여기를 참조 하십시오

더 이상 사용되지 않음 :

Android Developers 의이 게시물 에 따르면 이제 PercentRelativeLayout 또는 PercentFrameLayout 내에서 원하는 것을 랩핑 한 다음 비율을 지정하면됩니다.

<android.support.percent.PercentRelativeLayout 
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        app:layout_widthPercent="100%"
        app:layout_aspectRatio="100%"/>

</android.support.percent.PercentRelativeLayout>

8
이 답변의 링크는 Google이 제공 한 가장 훌륭한 솔루션입니다. 필자의 경우 원본 이미지 종횡비에 관계없이 이미지를 16 : 9 비율로 표시하려고했습니다. 잘 작동합니다. 감사!
LET

필자의 경우, 이와 같은 솔루션 작동하지 않았습니다.
Gooey

5
망가 의존성에 '컴파일 com.android.support:percent:23.3.0'을 추가하는 것을 잊지
밀라 드 Faridnia에게

이 방법은 자식 내용을 기반으로 높이를 계산하는 WrappedViewPager에 문제가있는 것처럼 보입니다. 유사 WrappedViewPager의 소스 gist.github.com/egslava/589b82a6add9c816a007

1
지원 중단 모듈은 더 이상 사용되지 않습니다. 안드로이드 지원 라이브러리 26.0.0부터 사용되지 않습니다. 출처 : developer.android.com/topic/libraries/support-library/…
MHogge

97

아마도 이것은 당신의 질문에 대답 할 것입니다 :

<ImageView
    android:id="@+id/cover_image"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:scaleType="fitCenter"
    android:adjustViewBounds="true" />

scaleType이 특정 상황에 대한 속성을 무시할 수 있습니다 .


12
네, 그건 쓸모가 없습니다
Fattie

4
필연적으로 쓸모가 없습니다. 이것은 내 사용법에 잘 작동합니다. 제목을 유지하면서 높이를 채울 수 있도록 제목 표시 줄에 아이콘이 있습니다.
Anubian Noob 2019

3
내 문제도 해결했다.
Dielson Sales

가장 쉬운 방법! 이것은 정답으로 표시되어야합니다.
H. Farid

30

런타임에 Views 너비를 알면 LayoutParams를 사용하여 Views 높이를 동적으로 설정할 수 있습니다. 런타임에 뷰 너비를 얻으려면 Runnable 스레드를 사용해야합니다. 그렇지 않으면 레이아웃이 아직 그려지지 않았기 때문에 뷰의 너비를 알기 전에 높이를 설정하려고합니다.

내 문제를 해결 한 방법의 예 :

final FrameLayout mFrame = (FrameLayout) findViewById(R.id.frame_id);

    mFrame.post(new Runnable() {

        @Override
        public void run() {
            RelativeLayout.LayoutParams mParams;
            mParams = (RelativeLayout.LayoutParams) mFrame.getLayoutParams();
            mParams.height = mFrame.getWidth();
            mFrame.setLayoutParams(mParams);
            mFrame.postInvalidate();
        }
    });

LayoutParams는보기가있는 부모보기 유형이어야합니다. 내 FrameLayout은 xml 파일의 RelativeLayout 안에 있습니다.

    mFrame.postInvalidate();

UI 스레드와 다른 스레드에있는 동안보기를 다시 그리도록 호출됩니다.


4
특히 Runnable에 대한 멋진 답변 감사합니다!
jesses.co.tt

1
이것이 효과가 있지만 이상적이지 않습니다. 포스트에서 실행하면 레이아웃이 변경되기 전에 뷰가 한 번 렌더링됩니다. 올바르게 그리기 전에 내용의 높이가 잘못된 높이로 플래시 될 수 있습니다. 일찍 해결하는 것이 좋습니다. 가장 빠른 해결 방법은 Regis의 답변onMeasure 에서 볼 수 있듯이 사용자 지정 중 입니다. 대안은 있지만 예를 들어 inside 등 의 어댑터를 통해 렌더링 된 뷰 의 경우 Matt의 답변 입니다. GridView
ToolmakerSteve

1
requestLayout()매개 변수를 설정 한 후 호출 한 후에 만 나에게 효과적 이었습니다. 왜 그럴까요?
Divins Mathew

mFrame.postInvalidate (); 그것 없이는 내가 견해를 벗어난 견해를 얻었습니다.
Jacolack

17

RecyclerView 항목에 대한 David Chu의 대답 을 얻지 못하고 ImageView를 부모에게 제한해야한다고 생각했습니다. ImageView 너비를로 설정 0dp하고 시작 및 끝을 부모로 제한하십시오. 너비를 설정 wrap_content하거나 match_parent일부 경우 작동 하는지 확실하지 않지만 ConstraintLayout의 자식이 부모를 채우는 더 좋은 방법이라고 생각합니다.

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintDimensionRatio="1:1"/>

</android.support.constraint.ConstraintLayout>

13

여기에 너비가 항상 높이와 같은 ImageButton을 사용하여 수행 한 것은 (한 방향으로 바보 같은 빈 여백을 피하십시오 ... SDK의 버그로 간주합니다 ...) :

ImageButton에서 확장되는 SquareImageButton 클래스를 정의했습니다.

package com.myproject;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageButton;

    public class SquareImageButton extends ImageButton {

        public SquareImageButton(Context context) {
        super(context);


        // TODO Auto-generated constructor stub
    }

    public SquareImageButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub

    }

    public SquareImageButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub

    }

    int squareDim = 1000000000;

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


        int h = this.getMeasuredHeight();
        int w = this.getMeasuredWidth();
        int curSquareDim = Math.min(w, h);
        // Inside a viewholder or other grid element,
        // with dynamically added content that is not in the XML,
        // height may be 0.
        // In that case, use the other dimension.
        if (curSquareDim == 0)
            curSquareDim = Math.max(w, h);

        if(curSquareDim < squareDim)
        {
            squareDim = curSquareDim;
        }

        Log.d("MyApp", "h "+h+"w "+w+"squareDim "+squareDim);


        setMeasuredDimension(squareDim, squareDim);

    }

}

내 XML은 다음과 같습니다.

<com.myproject.SquareImageButton
            android:id="@+id/speakButton"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:scaleType="centerInside"
            android:src="@drawable/icon_rounded_no_shadow_144px"
            android:background="#00ff00"
            android:layout_alignTop="@+id/searchEditText"
            android:layout_alignBottom="@+id/searchEditText"
            android:layout_alignParentLeft="true"
           />

매력처럼 작동합니다!


네, 그게 가장 좋은 대답입니다. (그리고 OPs 질문과 실제로 일치하는 유일한 것)
Twometer

6

Android 26.0.0에서는 PercentRelativeLayout이 더 이상 사용되지 않습니다. .

이를 해결하는 가장 좋은 방법은 ConstraintLayout다음과 같습니다.

<android.support.constraint.ConstraintLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

    <ImageView android:layout_width="match_parent"
               android:layout_height="0dp"
               android:scaleType="centerCrop"
               android:src="@drawable/you_image"                       
               app:layout_constraintDimensionRatio="1:1"/>


</android.support.constraint.ConstraintLayout>


다음은 프로젝트 에 추가하는 방법에 대한 자습서 입니다 ConstraintLayout.


6

이미지 뷰가 구속 조건 레이아웃 내에있는 경우 다음 구속 조건을 사용하여 정사각형 이미지 뷰를 작성할 수 있습니다.

<ImageView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:id="@+id/ivImageView"
    app:layout_constraintDimensionRatio="W,1:1"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"/>

5

레이아웃만으로는 할 수 없습니다. 시도했습니다. 처리하기 위해 매우 간단한 클래스를 작성 했으므로 github에서 확인할 수 있습니다. SquareImage.java 큰 프로젝트의 일부이지만 작은 복사 및 붙여 넣기로 해결할 수없는 부분은 없습니다 (Apache 2.0에서 라이센스 됨)

기본적으로 높이 / 너비를 다른 치수와 동일하게 설정해야합니다 (크기 조정 방법에 따라 다름)

참고 : scaleType속성을 사용하여 사용자 정의 클래스없이 정사각형을 만들 수 있지만 뷰의 경계는 보이는 이미지를 넘어 확장되므로 다른 뷰를 그 근처에 배치하면 문제가됩니다.


3

ImageView를 화면의 절반으로 설정하려면 ImageView의 XML에 다음을 추가해야합니다.

<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"
    android:scaleType="fitXY"
    android:adjustViewBounds="true"/>

그런 다음 높이를이 너비와 동일하게 설정하려면 코드에서 높이를 설정해야합니다. 어댑터 의 getView방법 GridView에서 ImageView높이를 측정 된 너비와 동일하게 설정하십시오 .

mImageView.getLayoutParams().height = mImageView.getMeasuredWidth();

3

지금 지나가는 사람들의 경우 2017 년에 ConstraintLayout 을 사용하여 원하는 것을 얻는 가장 좋은 새로운 방법은 다음과 같습니다.

<ImageView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:scaleType="centerCrop"
    app:layout_constraintDimensionRatio="1:1" />

레이아웃에 필요한 네 방향 모두에 제약 조건을 추가하는 것을 잊지 마십시오.

ConstraintLayout을 사용하여 반응 형 UI 구축

또한 현재 PercentRelativeLayout은 더 이상 사용되지 않습니다 ( Android 문서 참조 ).


1

그 문제를 해결 한 방법은 다음과 같습니다.

int pHeight =  picture.getHeight();
int pWidth = picture.getWidth();
int vWidth = preview.getWidth();
preview.getLayoutParams().height = (int)(vWidth*((double)pHeight/pWidth));

preview-너비가 "match_parent"로 설정되고 scaleType이 "cropCenter"로 설정된 imageView

picture-imageView src에서 설정할 비트 맵 객체입니다.

그것은 저에게 아주 잘 작동합니다.


이 코드를 어디에 두어야 하는지 설명하지 않았습니다 . 당신은 또한 왜 당신이 = vw*ph/pw더 간단한 대신 그렇게 설명하지 않았습니다 = vw. (정사각형 미리보기를 강요하지 않고 소스 이미지의 가로 세로 비율을 유지하기 위해이 작업을 수행한다고 생각합니다.)
ToolmakerSteve

0

XML 레이아웃 파일에서 할 수있는 방법이 없다고 생각하며 android:scaleType속성이 원하는대로 작동 한다고 생각하지 않습니다 .
유일한 방법은 프로그래밍 방식으로 수행하는 것입니다. 너비를 fill_parent로 설정하고 화면 너비를 높이로 View사용하거나 View.getWidth()메소드 를 사용할 수 있습니다 .


0

ImageView "scaleType"기능이 도움이 될 수 있습니다.

이 코드는 종횡비를 유지하고 이미지를 맨 위에 놓습니다.

android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitStart"

다음은 scaleType 사용의 가능성과 모양을 보여주는 훌륭한 게시물입니다.

ImageView scaleType 샘플


"scaleType"은 여기서 도움이되지 않습니다. 목표는 ImageView 자체가 이미지가 아니라 항상 정사각형이되도록하는 것입니다. scaleType을 사용하면 ImageView가 이미지보다 클 수 있습니다.
ToolmakerSteve

0

나는 이것을 좋아했다-

layout.setMinimumHeight(layout.getWidth());
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.