如何根据其父布局的大小设置视图大小。例如,我有一个填满整个屏幕的RelativeLayout
,我希望子视图(例如ImageView
)占据整个高度和1/2的宽度?
我已经尝试了覆盖所有onMeasure
、onLayout
、onSizeChanged
等方法,但都无法使其正常工作……
我不知道是否还有人在关注这个帖子,但Jeff的解决方案只能帮你完成一半(字面意思)。他的onMeasure将会在父视图的一半中展示出图片的一半。问题是,在调用setMeasuredDimension
之前调用super.onMeasure将会根据原始大小测量视图中的所有子元素,然后在setMeasuredDimension
重新调整大小时,只是将视图切成两半。
相反,您需要调用setMeasuredDimension
(对于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);
}
我相信只有在父布局是AbsoluteLayout
(已经被弃用但有时仍然有用)的情况下,您才会遇到与父LayoutParams
相关的问题。
MeasureSpec.getSize(widthMeasureSpec)
真的可以得到正确的父宽度吗?对我来说,它只返回接近实际宽度但不精确的随机宽度。 - Konsumiererwrap_content
不起作用。Vic的答案对于这种情况不起作用,但是@M.Schenk的评论可以解决。它还可以节省额外的布局传递。您还应该将其发布为可见性的答案。 - dokkaebisuper.onMeasure()
不会简单地覆盖和使早期调用的 this.setMeasuredDimension()
失效吗? - Spinnersuper.onMeasure()
没有覆盖先前的计算。 - jwir3你可以通过创建自定义视图并覆盖onMeasure()方法来解决此问题。如果你在xml中总是使用"fill_parent"作为layout_width,那么传递到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>
@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上定义布局和视图时,可以将视图的布局宽度和高度指定为wrap_content
或fill_parent
。占据一半区域有点困难,但如果您想在另一半上放置某些内容,可以尝试以下方法。
<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 来仅使用一个视图可以使其更加准确。我不再称其为“hack”,而是在我看来最直接的方法:
<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();
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(childWidth,childLength);
childView.setLayoutParams(params);
大概是这样的:
<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>