wrap_content高度,但仅限于父级的一半

时间:2012-10-18 01:37:17

标签: android layout

我想要的是具有垂直排列的2个视图的布局。让我们调用顶视图A和底部B.我希望给予B的高度是它的正常高度(即换行内容),除了我不希望给它超过可用空间的一半。得到了剩下的东西。

另一种说法是,A应该始终至少达到可用高度的50%,而B应该达到最多50%。

我似乎无法找到实现这一目标的简单方法。我可以将两个布局高度设置为0并赋予它们相同的权重,使它们总是50%,但如果B小于50%,则应该只给出它所需要的。

我能看到的唯一方法是使用A或B的自定义类并覆盖onMeasure将高度限制为父级的50%,但似乎应该有一种更简单的方法。

4 个答案:

答案 0 :(得分:3)

好的,我现在明白了。如果我理解正确你想要这样:

if A > B -> do nothing 
if B > A & B > parent layout -> 50% to both of them
if B > A & B < parent layout -> A = parent layout - B

我必须在onWindowFocusChanged中完成所有操作,因为否则在onCreate中,视图的高度将返回0.我使用2个LinearLayouts作为子布局,但你可以随心所欲。

我的XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:id="@+id/parent_lay"
    android:orientation="vertical"
    android:layout_height="match_parent" >

//Layout A:
    <LinearLayout
        android:id="@+id/lay_1"
        android:layout_width="match_parent"
       android:background="@android:color/background_dark"
        android:layout_height="10dp" >
    </LinearLayout>
//Layout B:
    <LinearLayout
        android:id="@+id/lay_2"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="#123456" >

    </LinearLayout>

</LinearLayout>

MainActivity:

public class MainActivity extends Activity {
    LinearLayout parent_lay;
    LinearLayout lay_1;
    LinearLayout lay_2;
    int parent_height;
    int lay_1_height;
    int lay_2_heigth;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        // TODO Auto-generated method stub
        super.onWindowFocusChanged(hasFocus);
        parent_lay = (LinearLayout) findViewById(R.id.parent_lay);
        lay_1 = (LinearLayout) findViewById(R.id.lay_1);
        lay_2 = (LinearLayout) findViewById(R.id.lay_2);
        lay_1_height = lay_1.getHeight();
        lay_2_heigth = lay_2.getHeight();
        parent_height = parent_lay.getHeight();


        if (lay_2.getHeight() > lay_1.getHeight()
                && lay_2.getHeight() > (parent_lay.getHeight() / 2)) {

            lay_1.setLayoutParams(new LinearLayout.LayoutParams(
                    LayoutParams.MATCH_PARENT, 0, 1));

            lay_2.setLayoutParams(new LinearLayout.LayoutParams(
                    LayoutParams.MATCH_PARENT, 0, 1));

        } else if (lay_2.getHeight() < (parent_lay.getHeight() / 2)) {
            lay_1.setLayoutParams(new LinearLayout.LayoutParams(
                    LayoutParams.MATCH_PARENT, (parent_height - lay_2_heigth)));

        }

    }

}

实施例: 如果A 60dp 且B 40dp

enter image description here

如果A 60dp 且B 400dp

enter image description here

答案 1 :(得分:0)

您必须编写自己的组件才能实现此目的。

例如,如果您在此处使用LinearLayout,则可以使用overdid onMeasure方法扩展LinearLayout。您可以像这样实现onMeasure:

@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    final int width = getMeasuredWidth();
    final int height = getMeasuredHeight();
    setMeasuredDimension(width, height / 2);
}

这段代码不够优雅。如果你真的想要做得好,请从Android源代码中复制原始的onMeasure方法(http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/ android / widget / LinearLayout.java#LinearLayout.onMeasure%28int%2Cint%29),并在measureVertical(int widthMeasureSpec, int heightMeasureSpec)中设置mTotalLength = mTotalLength / 2

有关onMeasure的详细信息,请访问http://developer.android.com/guide/topics/ui/custom-components.htmlhttp://developer.android.com/reference/android/view/View.html#onMeasure(int,int。

答案 2 :(得分:0)

现在可以使用ConstraintLayout实现所需的效果:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/containerFrameLayout"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.5"/>

    <FrameLayout
        android:id="@+id/containerFrameLayout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constrainedHeight="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/guideline"
        app:layout_constraintVertical_bias="1">

        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </FrameLayout>
</android.support.constraint.ConstraintLayout>

答案 3 :(得分:-1)

创建一个包含两个内部框架的线性布局,每个内部框架的权重为.5内部这些框架,放置您的观看次数,并根据需要将其设置为wrap_contentmatch_parent