线性布局权重在相对布局中不起作用

Linear Layout weights not working inside of Relative Layout

我自己和几个朋友正在为 android 制作一个有游戏场地的游戏。在比赛场地的一部分前面,我想放置按钮。像这样:

为了将一组 xml 放在另一组之前,我相信我们需要使用相对布局。到目前为止,我们一直在(以编程方式)内联执行此操作,但现在我想使用 XML 执行此操作。我想我非常了解权重的工作原理。我正在使用彼此内部的线性布局来做到这一点。预期的结果是让按钮只覆盖屏幕的一小部分。

不幸的是,当我将我的线性布局添加到我的相对布局时,加权功能似乎不再起作用。

为清楚起见,我添加了两行按钮并将第二行的权重设置为大于第一行。这是 Android Studio 布局的预览:

这是实际输出的内容:

两行显示为相同大小。我希望有人能给我一个关于为什么会发生这种情况的答案,如果可能的话,关于如何解决问题的解决方案。

这是我将线性布局添加到相对布局的代码:

RelativeLayout relativeLayout = (RelativeLayout)this.findViewById(R.id.testLayout);
View  view = LayoutInflater.from(this).inflate(R.layout.testgameplay_wrapper, null);
relativeLayout.addView(view);

这里是相关的XML。我创建了一个包装器 class 来简化事情:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
android:id="@+id/testScreenLinearWrapper"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout1"
    android:layout_weight=".25"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:orientation="horizontal">

    <include layout="@layout/testgameplay_buttondisplay"></include>

    </LinearLayout>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout2"
    android:layout_weight="1"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:orientation="horizontal">

    <include layout="@layout/testgameplay_buttondisplay"></include>

</LinearLayout>

编辑:

testgamplaybutton_buttondisplay.xml 根据要求:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
    android:id="@+id/testScreenButtonDisplay"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/linearLayoutInnermost1"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="horizontal">

            <include
                layout="@layout/defend_screen_buttons"></include>

        </LinearLayout>

        <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/linearLayoutInnermost2"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="horizontal">


            <include
                layout="@layout/test_screen_buttons"></include>

        </LinearLayout>

test_screen_buttons.xml 可能会被要求:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/testScreenButtons"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout1"
    android:layout_weight=".25"
    android:layout_height="match_parent"
    android:layout_width="0dp"
    android:orientation="horizontal">
<Button
    android:id="@+id/spawnCreepButton"
    android:textColor="@android:color/white"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerInParent="true"
    android:background="@drawable/basic_button"
    android:text="Spawn Creep"
    android:onClick="RunProjectileTest"/>

</LinearLayout>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout2"
    android:layout_weight=".25"
    android:layout_height="match_parent"
    android:layout_width="0dp"
    android:orientation="horizontal">

<Button
    android:id="@+id/sendCreepsButton"
    android:gravity="center"
    android:textColor="@android:color/white"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:background="@drawable/basic_button"
    android:text="Send Creeps"
    android:onClick="StartSendCreepsScreen"/>

</LinearLayout>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout3"
    android:layout_weight=".25"
    android:layout_height="match_parent"
    android:layout_width="0dp"
    android:orientation="horizontal">
<Button
    android:id="@+id/replayButton"
    android:gravity="center"
    android:textColor="@android:color/white"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:background="@drawable/basic_button"
    android:text="Replay"
    android:onClick="StartReplayScreen"/>

</LinearLayout>

defend_screen_buttons.xml 可能会被要求:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/buttonViewGroup"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout1"
    android:layout_weight=".25"
    android:layout_height="match_parent"
    android:layout_width="0dp"
    android:orientation="horizontal">

<Button
    android:id="@+id/startButton"
    android:textColor="@android:color/white"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerInParent="true"
    android:textSize="20sp"
    android:background="@drawable/basic_button"
    android:text="Start" />

    </LinearLayout>


<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout2"
    android:layout_weight=".25"
    android:layout_height="match_parent"
    android:layout_width="0dp"
    android:orientation="horizontal">

<Button
    android:id="@+id/sendButton"
    android:gravity="center"
    android:textColor="@android:color/white"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:background="@drawable/basic_button"
    android:text="Prepare Attack!" />

</LinearLayout>

现在你明白我为什么要简化它了吧 XD

感谢您的时间和专业知识!

为了在子View中使用layout_weight 属性,需要指定父View的weightSum。这适用于 LinearLayouts。 在下面的示例中,我已经声明了一个根 LinearLayout,其 weightSum 为 1,以及一个 layout_weight 等于 .5 的子视图,这样它将填满屏幕的一半。 这个子视图(包装器)的 weightSum 为 1.5,它内部有两个子视图,一个 layout_weight 等于 .5,另一个宽度 layout_weight 等于 1。注意这些LinearLayouts 的 weightSum 等于 1,因此内部的每个按钮都应该有一个 layout_weight 等于 .2,以便均匀分布。

希望对您有所帮助!

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

    <!-- Wrapper id View fills half of the screen, 0.5 and has a weightSum of 1.5-->
    <LinearLayout
        android:id="@+id/wrapper"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.5"
        android:weightSum="1.5"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight=".5"
            android:weightSum="1">
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
            <Button
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight=".2"/>
        </LinearLayout>

    </LinearLayout>

</LinearLayout>

在最外面的 LinearLayout 标签中,控制 android:layout_height 属性。因为它现在设置为 match_parent,所以它占据了整个屏幕。将它设置为某个绝对值(例如 200dp),您应该会看到差异。

我相信我已经找到了问题的答案。

这是我创建 LinearLayout 并将其添加到 RelativeLayout 的旧代码:

RelativeLayout relativeLayout = (RelativeLayout)this.findViewById(R.id.testLayout);
View  view = LayoutInflater.from(this).inflate(R.layout.testgameplay_wrapper, null);
relativeLayout.addView(view);

这是我的新代码:

    //Now using LinearLayout instead of View     
    LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    LinearLayout linearLayout = (LinearLayout)inflater.inflate(R.layout.testgameplay_buttondisplay, null);

    //convert dp to pixels
    int height = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics());

    //Set the height of the layout in newly calculated pixels
    RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, height);
    rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
    linearLayout.setLayoutParams(rlp);

    relativeLayout.addView(linearLayout);

如您所见,我正在使用 LayoutParams 并将它们添加到我的 linearLayout 中。这些按钮现在按照我的意愿出现在屏幕上,它们的大小根据我指示的像素高度而变化。感谢所有提供意见的人!

我对线性布局内的相对布局有同样的问题,偏离中心可能是个问题。我检查了所有的解决方案,但没有看到任何人在 layout_width 上使用 match_parent 作为线性视图的子项。将 0dpwrap_content 更改为 match_parent。这是我的问题之前和之后: