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

Mit*_*tch 100 layout android

如何根据其父布局的大小调整视图大小.例如,我有一个RelativeLayout填满整个屏幕,我想要一个儿童视图,比如说ImageView,占据整个高度,宽度的1/2?

我试图重写所有的onMeasure,onLayout,onSizeChanged,等我无法得到它的工作....

Vic*_*Vic 122

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

我相信你唯一一次遇到父母的问题LayoutParams就是如果父母是一个AbsoluteLayout(已经弃用但有时仍然有用).

  • 根据我的经验,这很少奏效,尤其是.当调用fill/match_parent或权重时.最好在setMeasuredDimension之后调用measureChildren(例如MeasureSpec.makeMeasureSpec(newWidth,MeasureSpec.AT_MOST)). (11认同)
  • 调用`super.onMeasure()`是否会简单地覆盖并取消之前调用`this.setMeasuredDimension()`的效果? (7认同)

小智 39

您可以通过创建自定义视图并覆盖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);
    }
}   
Run Code Online (Sandbox Code Playgroud)

您的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>
Run Code Online (Sandbox Code Playgroud)

  • @Leon_SFS:问题是:"整个高度,宽度的1/2" (6认同)
  • @jeff =>为什么parentWidth/2 ?? (2认同)

Phi*_*lak 26

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

但是,你可以做的是修改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);
}
Run Code Online (Sandbox Code Playgroud)


Che*_*mon 16

在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>
Run Code Online (Sandbox Code Playgroud)

赋予两个相同重量的东西意味着它们会拉伸以占据相同比例的屏幕.有关布局的更多信息,请参阅开发文档.


小智 9

我相信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>
Run Code Online (Sandbox Code Playgroud)

像这样你可以使用任何重量,例如0.6(和居中)是我喜欢用于按钮的重量.