如何根据父视图的尺寸调整Android视图的大小

时间:2010-01-29 01:30:47

标签: android layout

如何根据父布局的大小调整视图大小。例如,我有一个RelativeLayout填充整个屏幕,我想要一个子视图,比如一个ImageView,占据整个高度,宽度是1/2?

我已尝试在onMeasureonLayoutonSizeChanged等上覆盖所有内容,但我无法让它工作....

11 个答案:

答案 0 :(得分:122)

我不知道是否有人还在读这个帖子,但杰夫的解决方案只会让你到达那里(有点字面)。他的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);
}

我认为,如果父级LayoutParams(已被弃用但有时仍然有用),则父母AbsoluteLayout唯一有问题的时候就会出现问题。

答案 1 :(得分:38)

您可以通过创建自定义视图并覆盖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>

答案 2 :(得分:25)

我发现最好不要自己设置测量尺寸。父视图和子视图之间实际上有一些协商,你不想重写所有code

但是,你可以做的是修改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);
}

答案 3 :(得分:15)

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

给两个相同重量的东西意味着它们会拉伸以占据相同比例的屏幕。有关布局的更多信息,请参阅the dev docs.

答案 4 :(得分:9)

我相信Mayras XML-approach可以整齐。但是,只有通过设置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(和居中)是我喜欢用于按钮的重量。

答案 5 :(得分:3)

试试这个

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

答案 6 :(得分:2)

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

答案 7 :(得分:1)

Roman,如果你想在Java代码(ViewGroup后代)中进行布局,那就有可能。诀窍是你必须同时实现onMeasure和onLayout方法。 首先调用onMeasure,然后你需要“测量”子视图(有效地将其调整到所需的值)。您需要在onLayout调用中再次调整大小。如果您未能执行此序列或未能在onMeasure代码的末尾调用setMeasuredDimension(),则无法获得结果。为什么这种复杂而脆弱的设计方式超出了我的范围。

答案 8 :(得分:1)

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

这适用于LinearLayout ......

答案 9 :(得分:0)

它是这样的:

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

答案 10 :(得分:-1)

我一直在努力解决这个问题,我想更改DrawerLayout的抽屉宽度,这是其父项的第二个孩子。 最近我想通了,但不知道是否有更好的主意。

override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
    super.onLayout(changed, l, t, r, b)
    (getChildAt(1).layoutParams as LayoutParams).width = measuredWidth/2
}