如何划分元素之间的空间? Android的

时间:2014-12-24 23:49:46

标签: android xml android-layout

最后我遇到了一些有趣的问题。当我想在屏幕上精确划分某些元素之间的位置时,我通常使用LinearLayout,放入我的元素并给它们一些权重。它适用于2个元素而且更多,但是当我想在更多不同的部分(20 | 60 | 20)上划分屏幕然后将它们分开时,它变得非常令人沮丧。

我该怎么办?我希望我的布局在不同的屏幕上看起来相同,因此在小屏幕和大屏幕上边距会有所不同。因此,例如,如果我希望我的按钮占据屏幕宽度的60%,我被迫在两侧添加20%的空间。

我实际上是使用权重,但我的xml代码如下所示:

<LinearLayout
. . .
android:orientation="vertical"
android:weightSum="0">


<TextView
    . . .
    android:layout_weight="67"/>

<LinearLayout
    . . .
    android:orientation="horizontal"
    android:layout_weight="59"
    android:weightSum="0">


    <TextView
        . . .
        android:layout_weight="80"/>

    <ImageView
        . . .
        android:layout_weight="10"/>

    <TextView
        . . .
        android:layout_weight="80"/>



</LinearLayout>

<TextView
    . . .
    android:layout_weight="50"/>

<LinearLayout
    . . .
    android:orientation="horizontal"        
    android:weightSum="0">


    <TextView
        . . .
        android:layout_weight="70"/>

    <LinearLayout
        . . .
        android:orientation="vertical"
        android:weightSum="0">

        <TextView
            . . .
            android:layout_weight="65"/>

        <EditText
            . . .
            android:layout_weight="50"/>

        <TextView
            . . .
            android:layout_weight="75"/>

        <EditText
            . . .
            android:layout_weight="50"/>

        <TextView
            . . .
            android:layout_weight="65"/>


        </LinearLayout>

    <TextView
        . . .
        android:layout_weight="70"/>


</LinearLayout>

<LinearLayout
    . . .
    android:orientation="horizontal"
    android:weightSum="0">

    <TextView
        . . .
        android:layout_weight="80"/>

    <LinearLayout
        . . .
        android:orientation="vertical"
        android:layout_weight="60">

        <TextView
            . . .
            android:layout_weight="80"/>

        <Button
            . . .              
            android:layout_weight="60"/>

        <TextView
            . . .
            android:layout_weight="50"/>

    </LinearLayout>


    <TextView
        . . .
        android:layout_weight="80"/>



</LinearLayout>

<LinearLayout
    . . .
    android:orientation="horizontal"
    android:layout_weight="65"
    android:weightSum="0"
    >

    <Button            
        android:layout_weight="1"
        . . ./>

    <Button            
        android:layout_weight="1"
        . . ./>

    <Button            
        android:layout_weight="1"
        . . ./>

</LinearLayout>

正如你所看到的那样,有许多空文本视图除了在布局上占据一席之外什么都不做。是否有更聪明,更不令人沮丧的方法来精确划分元素之间的屏幕位置?

很高兴听到任何建议!

2 个答案:

答案 0 :(得分:3)

使用LinearLayout和权重时,有几点要记住并不明显:

  1. 将LinearLayout的weightSum设置为您要分配的权重总和
  2. 如果使用权重作为宽度,那么LinearLayout中的所有项目都应将其layout_width设置为0(是,0 ......这也很重要)
  3. 重量和重量不必是整数;例如,您可以指定权重2.5。
  4. 所以,直接回答你的问题,这是我认为你想要的布局。我做了一个简单的水平LinearLayout,左边和右边的空白视图,重量为20%,然后是一个中心的按钮,总重量为60%。以下是各种屏幕尺寸的样子,下面是XML代码:

    enter image description here

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="100dp"
      android:orientation="horizontal"
      android:background="@android:color/holo_blue_bright"
      android:weightSum="100.0"
      >
      <View
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="20.0"
        android:background="@android:color/holo_green_dark"
        />
      <Button
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="60.0"
        android:background="@android:color/holo_red_light"
        android:text="Hello, I am button"
        />
      <View
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="20.0"
        android:background="@android:color/holo_green_dark"
        />
    </LinearLayout>
    

    编辑:这是更新的XML,它具有嵌套权重并且性能很差(请参阅注释)...建议使用RelativeLayout并以dp中测量的边距/填充为中心,以保持屏幕大小之间的一致性。< / p>

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="100dp"
      android:orientation="horizontal"
      android:background="@android:color/holo_blue_bright"
      android:weightSum="100.0"
      >
      <View
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="20.0"
        android:background="@android:color/holo_green_dark"
        />
      <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="60.0"
        android:weightSum="99.9"
        >
        <Button
          android:layout_width="match_parent"
          android:layout_height="0dp"
          android:layout_weight="33.3"
          android:text="Hello, I am button1"
          android:background="@android:color/holo_red_light"
          />
        <Button
          android:layout_width="match_parent"
          android:layout_height="0dp"
          android:layout_weight="33.3"
          android:text="Hello, I am button2"
          android:background="@android:color/holo_red_light"
          />
        <Button
          android:layout_width="match_parent"
          android:layout_height="0dp"
          android:layout_weight="33.3"
          android:text="Hello, I am button3"
          android:background="@android:color/holo_red_light"
          />
      </LinearLayout>
      <View
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="20.0"
        android:background="@android:color/holo_green_dark"
        />
    </LinearLayout>
    

答案 1 :(得分:2)

由于您需要嵌套权重来执行您想要执行的操作,因此在Java代码中,在ViewTreeObserver.OnGlobalLayoutListener中执行此操作会更有效。下面是一个如何执行此操作的示例(此外,它仅在初始布局期间触发一次,然后自行删除,以便您不会无缘无故地重复执行此操作):

当然,您可以将Button替换为另一个RelativeLayout或LinearLayout,以使视图看起来如您所愿,但在onGloablLayout()方法中,您可以确保屏幕测量有效。在这个位置,您可以在一个布局周期中使用Java手动调整所有嵌套百分比,而不是使用嵌套权重时所采用的指数性能命中。

如果您需要进一步说明,请与我们联系。

这个例子位于Fragment的onCreateView()覆盖中,人们通常会在其中找到视图并设置样式:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    final View createdView = super.onCreateView(inflater, container, savedInstanceState);
    final Button button = (Button) createdView.findViewById(R.id.i_am_button);
    createdView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        public void onGlobalLayout()
        {
            DisplayMetrics displayMetrics = createdView.getContext().getResources().getDisplayMetrics();
            Log.d(TAG, "Screen Width x Height in Pixels: " + displayMetrics.widthPixels + " x " + displayMetrics.heightPixels);
            button.getLayoutParams().width = 0.60 * displayMetrics.widthPixels;
            button.requestLayout();
            createdView.getViewTreeObserver().removeOnGlobalLayoutListener(this);  //One-shot!
        }
    });
    return createdView;
}

这将假设一个XML布局,其中Button在RelativeLayout中水平居中,以便按照您的描述工作。

为清晰起见,这是一个示例XML代码段:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="150dp"
  android:background="@android:color/holo_blue_bright"
  >
  <Button
    android:id="@+id/i_am_button"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_centerHorizontal="true"
    android:background="@android:color/holo_red_dark"
    android:text="Hello, I am button"
    />
</RelativeLayout>