【问题标题】:Make a view take the rest of available space, if any使视图占用剩余的可用空间(如果有)
【发布时间】:2014-09-26 12:33:36
【问题描述】:

我正在尝试使用以下显示逻辑在 Android 中实现布局:

[ Left ][ Right ]
[    Bottom     ]

Left 有时比Bottom 宽,有时更窄。当BottomLeft 宽时,我希望Right 一直延伸到Bottom 的右边缘;当Left 更宽时,我希望Right 的宽度为0px。

LeftBottom 的性质并不那么重要;它们都是 wrap_content 的。

我尝试过在顶层使用 LinearLayout 和 RelativeLayout。无论我做什么,要么最外层容器的宽度由Bottom 驱动,与Left 无关,要么视图扩展不合理,要么Right 始终为零宽度。

这是我对 RelativeLayout 的最新尝试:

<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="78dp"
    >

    <TextView
         android:id="@+id/Left"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="Left"/>

    <View
        android:id="@+id/Right"
        android:layout_width="0dp"
        android:layout_toRightOf="@+id/Left"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_height="1px"
        android:layout_marginTop="32dp"
        android:background="#ffffffff"/>

    <TextView
        android:id="@+id/Bottom"
        android:layout_width="wrap_content"
        android:layout_height="23dp"
        android:layout_below="@+id/Left"
        android:layout_alignParentLeft="true"
        android:textColor="#ffff00"
        android:text="Hello"
        android:lines="1"/>
</RelativeLayout>

它没有按预期工作; Right 视图被不合理地拉伸。

在 4.4.2 模拟器上测试。如果重要的话,整个事情都在 ScrollView 中。目标 SDK 为 17。

【问题讨论】:

  • 我宁愿使用 LinearLayout 及其 layout_weigth 属性而不是 RelativeLayout
  • 你是否将宽度设置为 0,并尝试权重?
  • 是的,除此之外。

标签: android android-layout


【解决方案1】:

如果我正确理解了您的问题,那么这应该可行:

我将 Left 和 Right 放在父布局中,并将另一个 textview 放在该父容器下方。相应地设置高度。

<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="78dp"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.tempp.MainActivity" >

    <RelativeLayout
        android:id="@+id/upper"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/Left"
            android:layout_width="wrap_content"
            android:layout_height="32dp"
            android:text="Here I have written some text which is long" />

        <View
            android:id="@+id/Right"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_alignParentTop="true"
            android:layout_marginTop="32dp"
            android:layout_toRightOf="@+id/Left"
            android:background="#000000" />
    </RelativeLayout>

    <TextView
        android:id="@+id/Bottom"
        android:layout_width="wrap_content"
        android:layout_height="23dp"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/upper"
        android:lines="1"
        android:text="Hello"
        android:textColor="#ffff00" />

</RelativeLayout>

由此我得到以下输出:

第一种情况:(Left TextView 中带有短文本)

第二种情况:(Left TextView 的文本很长,但文本包含在一行中)

第三种情况:(文字超过1行)

希望这会有所帮助。

P.S:由于外部布局的高度,第二行 textview 的文本被剪掉了一点,我保留了它在你的问题中的样子。

编辑:

这是第二行文本比第一行文本长时的输出。

【讨论】:

  • 如果左边的文字比“Hello”短怎么办?或者,等效地,如果您将“Hello”替换为长行?
  • @SevaAlekseyev 在更改了您所说的两个文本后添加了屏幕截图。
  • 我最终实现了另一个,但这也很好。 +1
【解决方案2】:

我认为自定义视图可以解决您的问题。我稍微改变了你的布局,并包裹在一个自定义的相对布局中。我检查了自定义相对布局的子 OnLayout 事件的宽度。如果左边比底部宽,右边不会改变。否则,右边的宽度设置为宽度差。只保留一次布尔值以执行此操作。否则,布局的变化会导致对 OnLayout 方法的递归调用。

这是自定义类:

public class CustomRelativeLayout extends RelativeLayout {

private boolean mIsLayoutSet = false;

public CustomRelativeLayout(Context context) {
    super(context);
}

public CustomRelativeLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public CustomRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);

    if (!mIsLayoutSet) {
        View left = findViewById(R.id.Left);
        View right = findViewById(R.id.Right);
        View bottom = findViewById(R.id.Bottom);

        int leftWidth = left.getWidth();
        int bottomWidth = bottom.getWidth();

        if (bottomWidth > leftWidth) {
            LayoutParams params = (LayoutParams) right.getLayoutParams();
            params.width = bottomWidth - leftWidth;
            right.setLayoutParams(params);
        }

        mIsLayoutSet = true;
    }
}

}

以及自定义布局的用法:

<com.rotasoftc.myapps.CustomRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<TextView
    android:id="@+id/Left"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Left"/>

<View
    android:id="@+id/Right"
    android:layout_width="0dp"
    android:layout_toRightOf="@+id/Left"
    android:layout_height="15px"
    android:background="@android:color/black"
    android:layout_marginTop="7dp"/>

<TextView
    android:id="@+id/Bottom"
    android:layout_width="wrap_content"
    android:layout_height="23dp"
    android:layout_below="@+id/Left"
    android:layout_alignParentLeft="true"
    android:textColor="#ffff00"
    android:text="HelloHelloHelloHello"
    android:lines="1"/>
</com.rotasoftc.myapps.CustomRelativeLayout>

【讨论】:

  • 有点作弊,但我会接受它:)
猜你喜欢
  • 1970-01-01
  • 2013-07-12
  • 2019-09-23
  • 2013-02-22
  • 1970-01-01
  • 1970-01-01
  • 2018-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多