如何根据父级的维度来确定Android视图的大小
如何根据其父级布局的大小调整视图的大小。 例如,我有一个填充整个屏幕的RelativeLayout
,我想要一个孩子的视图,说一个ImageView
,占据整个高度,宽度的一半?
我已经尝试覆盖所有关于onMeasure
, onLayout
, onSizeChanged
等,我无法得到它的工作….
我不知道是否有人还在读这个post,但是杰夫的解决scheme只会让你在一半(有点字面上)。 他的onMeasure将做的是显示在一半的父母的形象的一半。 问题是,在setMeasuredDimension之前调用super.onMeasure将根据原始大小来测量视图中的所有子项,然后在setMeasuredDimension
resize时将视图切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; } }