이미지 뷰가 있습니다. 너비를 fill_parent로 설정하고 싶습니다. 높이가 너비가 무엇이든 되길 원합니다. 예를 들면 다음과 같습니다.
<ImageView
android:layout_width="fill_parent"
android:layout_height="whatever the width ends up being" />
내 자신의 뷰 클래스를 만들지 않고도 레이아웃 파일에서 이와 같은 것이 가능합니까?
감사
이미지 뷰가 있습니다. 너비를 fill_parent로 설정하고 싶습니다. 높이가 너비가 무엇이든 되길 원합니다. 예를 들면 다음과 같습니다.
<ImageView
android:layout_width="fill_parent"
android:layout_height="whatever the width ends up being" />
내 자신의 뷰 클래스를 만들지 않고도 레이아웃 파일에서 이와 같은 것이 가능합니까?
감사
답변:
업데이트 : 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>
아마도 이것은 당신의 질문에 대답 할 것입니다 :
<ImageView
android:id="@+id/cover_image"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:adjustViewBounds="true" />
scaleType이 특정 상황에 대한 속성을 무시할 수 있습니다 .
런타임에 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 스레드와 다른 스레드에있는 동안보기를 다시 그리도록 호출됩니다.
onMeasure 에서 볼 수 있듯이 사용자 지정 중 입니다. 대안은 있지만 예를 들어 inside 등 의 어댑터를 통해 렌더링 된 뷰 의 경우 Matt의 답변 입니다. GridView
requestLayout()매개 변수를 설정 한 후 호출 한 후에 만 나에게 효과적 이었습니다. 왜 그럴까요?
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>
여기에 너비가 항상 높이와 같은 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"
/>
매력처럼 작동합니다!
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.
이미지 뷰가 구속 조건 레이아웃 내에있는 경우 다음 구속 조건을 사용하여 정사각형 이미지 뷰를 작성할 수 있습니다.
<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"/>
레이아웃만으로는 할 수 없습니다. 시도했습니다. 처리하기 위해 매우 간단한 클래스를 작성 했으므로 github에서 확인할 수 있습니다. SquareImage.java 큰 프로젝트의 일부이지만 작은 복사 및 붙여 넣기로 해결할 수없는 부분은 없습니다 (Apache 2.0에서 라이센스 됨)
기본적으로 높이 / 너비를 다른 치수와 동일하게 설정해야합니다 (크기 조정 방법에 따라 다름)
참고 : scaleType속성을 사용하여 사용자 정의 클래스없이 정사각형을 만들 수 있지만 뷰의 경계는 보이는 이미지를 넘어 확장되므로 다른 뷰를 그 근처에 배치하면 문제가됩니다.
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();
지금 지나가는 사람들의 경우 2017 년에 ConstraintLayout 을 사용하여 원하는 것을 얻는 가장 좋은 새로운 방법은 다음과 같습니다.
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="1:1" />
레이아웃에 필요한 네 방향 모두에 제약 조건을 추가하는 것을 잊지 마십시오.
ConstraintLayout을 사용하여 반응 형 UI 구축
또한 현재 PercentRelativeLayout은 더 이상 사용되지 않습니다 ( Android 문서 참조 ).
그 문제를 해결 한 방법은 다음과 같습니다.
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. (정사각형 미리보기를 강요하지 않고 소스 이미지의 가로 세로 비율을 유지하기 위해이 작업을 수행한다고 생각합니다.)
ImageView "scaleType"기능이 도움이 될 수 있습니다.
이 코드는 종횡비를 유지하고 이미지를 맨 위에 놓습니다.
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitStart"
다음은 scaleType 사용의 가능성과 모양을 보여주는 훌륭한 게시물입니다.