Answers:
我不知道是否有人还在读这个线程,但是Jeff的解决方案只会使您半途而废(按字面意思)。他的onMeasure所要做的就是在一半的父对象中显示一半的图像。问题在于,在之前调用super.onMeasure setMeasuredDimension
会根据原始大小测量视图中的所有子项,然后在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);
}
我相信,只有在父母LayoutParams
是父母的情况下,父母才会遇到问题AbsoluteLayout
(不赞成使用,但有时还是有用的)。
MeasureSpec.getSize(widthMeasureSpec)
真的给出正确的parent's宽度是多少?对我来说,它只是返回随机宽度,该宽度与实际宽度非常接近,但不精确。
wrap_content
不会。Vic的答案在这种情况下不起作用,但是@ M.Schenk的注释可以。它还节省了额外的布局通行证。您还应该将其发布为可见性的答案。
super.onMeasure()
简单地覆盖并取消先前对的调用的影响this.setMeasuredDimension()
吗?
super.onMeasure()
不会覆盖先前的计算。
您可以通过创建自定义View并覆盖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>
赋予两个物体相同的重量意味着它们将拉伸以占据屏幕的相同比例。有关布局的更多信息,请参见dev文档。
我相信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();
那么您可以使用LinearLayout.LayoutParams设置chileView的参数
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(childWidth,childLength);
childView.setLayoutParams(params);
您现在可以使用PercentRelativeLayout。繁荣!问题解决了。
罗马,如果您想使用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>