如何根据父级的维度来确定Android视图的大小

如何根据其父级布局的大小调整视图的大小。 例如,我有一个填充整个屏幕的RelativeLayout ,我想要一个孩子的视图,说一个ImageView ,占据整个高度,宽度的一半?

我已经尝试覆盖所有关于onMeasureonLayoutonSizeChanged等,我无法得到它的工作….

我不知道是否有人还在读这个post,但是杰夫的解决scheme只会让你在一半(有点字面上)。 他的onMeasure将做的是显示在一半的父母的形象的一半。 问题是,在setMeasuredDimension之前调用super.onMeasure将根据原始大小来测量视图中的所有子项,然后在setMeasuredDimensionresize时将视图切setMeasuredDimension

相反,您需要调用setMeasuredDimension (根据onMeasure覆盖的需要) 为视图提供新的LayoutParams然后调用super.onMeasure 。 记住,你的LayoutParams派生自视图的父types,而不是视图的types。

 @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

你可以通过创build一个自定义的视图来解决这个问题,并覆盖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="fill_parent" android:layout_height="fill_parent"> <view class="com.company.MyCustomView" android:layout_width="fill_parent" android:layout_height="fill_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(和居中)是我喜欢用于button的重量。

尝试这个

 int parentWidth = ((parentViewType)childView.getParent()).getWidth(); int parentHeight = ((parentViewType)childView.getParent()).getHeight(); 

那么你可以使用LinearLayout.LayoutParams来设置chileView的参数

 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(childWidth,childLength); childView.setLayoutParams(params); 

您现在可以使用PercentRelativeLayout。 繁荣! 问题解决了。

罗马,如果你想在Java代码(ViewGroup后代)中做你的布局,这是可能的。 诀窍是你必须实现onMeasure和onLayout方法。 onMeasure首先被调用,你需要“测量”子视图(有效地调整到所需的值)。 您需要在onLayout调用中重新resize。 如果您未能完成这个序列,或者未能在onMeasure代码的末尾调用setMeasuredDimension(),则不会得到结果。 为什么这种复杂而脆弱的devise超出了我的想象。

如果对方是空的。 我想最简单的方法是添加一个空的视图(例如线性布局),然后将两个视图的宽度设置为fill_parent,并将其权重设置为1。

这在LinearLayout中工作…

这是这样的:

 <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> 

我有其他解决scheme。 我们可以得到父母的宽度和高度,然后用它来计算大小并分配给布局参数。
喜欢这个:

 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // Don't for get this int parentWidth = ((View) getParent()).getMeasuredWidth(); int parentHeight = ((View) getParent()).getMeasuredHeight(); if (parentWidth*parentHeight != 0) { // Check if both width and height in non-zero LayoutParams lp = getLayoutParams(); lp.width = parentWidth / 2; lp.height = parentHeight; } }