상위 레이아웃의 크기를 기준으로보기의 크기를 조정하려면 어떻게해야합니까? 예를 들어 RelativeLayout
전체 화면을 채우는가 있고 ImageView
, 전체 높이를 차지하고 너비의 1/2을 차지하는 하위보기 (예 :)를 원합니까?
나는 모든을 무시하려고했습니다 onMeasure
, onLayout
, onSizeChanged
... 등 내가 작업에 가져올 수 없습니다
상위 레이아웃의 크기를 기준으로보기의 크기를 조정하려면 어떻게해야합니까? 예를 들어 RelativeLayout
전체 화면을 채우는가 있고 ImageView
, 전체 높이를 차지하고 너비의 1/2을 차지하는 하위보기 (예 :)를 원합니까?
나는 모든을 무시하려고했습니다 onMeasure
, onLayout
, onSizeChanged
... 등 내가 작업에 가져올 수 없습니다
답변:
누군가가 여전히이 스레드를 읽고 있는지 여부는 알 수 없지만 Jeff의 솔루션은 (말 그대로) 절반 정도만 얻을 수 있습니다. 그의 onMeasure는 부모의 절반에 이미지의 절반을 표시합니다. 문제는 이전에 super.onMeasure를 호출 setMeasuredDimension
하면 원래 크기를 기준으로 뷰의 모든 하위 항목을 측정 한 다음 setMeasuredDimension
크기를 조정할 때 뷰를 반으로 자르는 것입니다.
대신 호출 할 필요 setMeasuredDimension
(AN 된 onMeasure 재정에 필요한) 과 새로운를 제공 LayoutParams
,보기에 대한 다음 호출 super.onMeasure
. 당신의 기억 LayoutParams
보기의 부모 유형,하지 뷰의 유형에서 파생됩니다.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(parentWidth/2, parentHeight);
this.setLayoutParams(new *ParentLayoutType*.LayoutParams(parentWidth/2,parentHeight));
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
부모에게 문제가 생길 수있는 유일한 LayoutParams
경우는 부모가 AbsoluteLayout
(더 이상 사용되지 않지만 때로는 유용함) 경우입니다.
MeasureSpec.getSize(widthMeasureSpec)
정말 올바른 parent's는 폭주는? 나를 위해 그것은 실제 너비에 매우 가깝지만 정확하지는 않은 임의의 너비를 반환합니다.
wrap_content
하지 않을 것입니다. Vic의 대답은이 시나리오에서 작동하지 않지만 @ M.Schenk의 의견은 작동합니다. 또한 추가 레이아웃 패스를 저장합니다. 가시성을위한 답변으로도 게시해야합니다.
super.onMeasure()
단순히 오버라이드 (override)에 대한 이전 호출의 효과를 무효화 this.setMeasuredDimension()
?
super.onMeasure()
이 이전 계산을 재정의하지 않는 이유도 궁금 합니다.
사용자 정의보기를 만들고 onMeasure () 메서드를 재정 의하여이 문제를 해결할 수 있습니다. xml의 layout_width에 항상 "fill_parent"를 사용하는 경우 onMeasusre () 메서드에 전달되는 widthMeasureSpec 매개 변수에 부모의 너비가 포함되어야합니다.
public class MyCustomView extends TextView {
public MyCustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(parentWidth / 2, parentHeight);
}
}
XML은 다음과 같습니다.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<view
class="com.company.MyCustomView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
측정 치수를 직접 설정하지 않는 것이 가장 좋습니다. 실제로 부모와 자식보기간에 진행되는 약간의 협상이 있으며 모든 코드 를 다시 작성하고 싶지는 않습니다 .
하지만 할 수있는 일은 measureSpecs를 수정 한 다음 super를 호출하는 것입니다. 당신의 뷰는 그것이 부모로부터 수정 된 메시지를 받고 있다는 것을 결코 알지 못할 것이며 당신을 위해 모든 것을 처리 할 것입니다.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
int myWidth = (int) (parentHeight * 0.5);
super.onMeasure(MeasureSpec.makeMeasureSpec(myWidth, MeasureSpec.EXACTLY), heightMeasureSpec);
}
XML에서 레이아웃과보기를 정의 할 때보기의 레이아웃 너비와 높이를 줄 바꿈 콘텐츠로 지정하거나 상위 항목을 채울 수 있습니다. 영역의 절반을 차지하는 것은 조금 더 어렵지만, 다른 절반에 원하는 것이 있다면 다음과 같이 할 수 있습니다.
<LinearLayout android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView android:layout_height="fill_parent"
android:layout_width="0dp"
android:layout_weight="1"/>
<ImageView android:layout_height="fill_parent"
android:layout_width="0dp"
android:layout_weight="1"/>
</LinearLayout>
두 가지에 같은 무게를 주면 화면의 같은 비율을 차지하도록 늘어납니다. 레이아웃에 대한 자세한 내용 은 개발 문서를 참조하세요 .
저는 Mayras XML 접근 방식 이 깔끔하게 올 수 있다고 믿습니다 . 그러나 weightSum을 설정하는 것만으로 하나의 뷰로 더 정확하게 만들 수 있습니다. 나는 이것을 더 이상 해킹이라고 부르지 않지만 내 의견으로는 가장 간단한 접근 방식입니다.
<LinearLayout android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:weightSum="1">
<ImageView android:layout_height="fill_parent"
android:layout_width="0dp"
android:layout_weight="0.5"/>
</LinearLayout>
이와 같이 모든 가중치를 사용할 수 있습니다. 예를 들어 0.6은 버튼에 사용하는 가중치입니다.
이 시도
int parentWidth = ((parentViewType)childView.getParent()).getWidth();
int parentHeight = ((parentViewType)childView.getParent()).getHeight();
그런 다음 chileView의 매개 변수를 설정하기 위해 LinearLayout.LayoutParams를 사용할 수 있습니다.
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(childWidth,childLength);
childView.setLayoutParams(params);
이제 PercentRelativeLayout을 사용할 수 있습니다. 팔! 문제 해결됨.
Roman, Java 코드 (ViewGroup 하위 항목)로 레이아웃을 수행하려는 경우 가능합니다. 트릭은 onMeasure 및 onLayout 메서드를 모두 구현해야한다는 것입니다. onMeasure가 먼저 호출되고 거기에서 하위 뷰를 "측정"해야합니다 (효과적으로 원하는 값으로 크기 조정). onLayout 호출에서 크기를 다시 조정해야합니다. 이 시퀀스를 수행하지 않거나 onMeasure 코드 끝에서 setMeasuredDimension () 호출에 실패하면 결과를 얻을 수 없습니다. 왜 이것이 그렇게 복잡하고 깨지기 쉬운 방식으로 설계 되었는가?
다음과 같습니다.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.company.myapp.ActivityOrFragment"
android:id="@+id/activity_or_fragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/linearLayoutFirst"
android:weightSum="100"> <!-- Overall weights sum of children elements -->
<Spinner
android:layout_width="0dp" <!-- It's 0dp because is determined by android:layout_weight -->
android:layout_weight="50"
android:layout_height="wrap_content"
android:id="@+id/spinner" />
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_below="@+id/linearLayoutFirst"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="@+id/linearLayoutSecond">
<EditText
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="75"
android:inputType="numberDecimal"
android:id="@+id/input" />
<TextView
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="25"
android:id="@+id/result"/>
</LinearLayout>
</RelativeLayout>