原文地址:http://cyrilmottier.com/2014/11/17/grid-spacing-on-android/?
大多数用户接口-在移动和web上-都是基于网格的概念。在一堆对齐的空间中,网格主要的组成分隔了用户接口,这些空间能被合并起来创建块。当设计UI的时候使用网格原理帮助对其元素,也带来一致性,清理代码,确保用户能容易的解析UI的内容等等。简单来说,网格式一个极其有用的设计工具。
使用网格概念通常要求开发人员在元素之间添加一些额外的padding/margin/spacing(选择最适合你的样式的名字。。。)。的确,当维护可读性非常高的UI时,在元素之间添加间隔帮助在块之间维护一个清楚的间隔。所有的Android开发者对那些概念是熟悉的并且很多时候确实是通过使用框架特性解决问题的,像视图中的padding和margin。为了清楚的从UI众隔离逻辑,这些属性通常会在定义的XML接口中完成。然而当UI是完全静态的时候,这个工作量特别大,它也许管理动态UI会变得更困难,在这种情况下元素及时的隐藏或者显示。这篇文章给了我们一些建议和技巧来更好的管理动态网格UI。
我们来创建一个简单的布局当例子。我们创建一个出现在一个静态视图下面的水平按钮条(例如应用程序logo)。下面的布局展现了在被给的图片中:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="@dimen/spacing_medium"> <TextView android:layout_width="match_parent" android:layout_height="128dp" android:background="@color/light_gray" android:gravity="center" android:text="@string/application_logo" android:textAppearance="@android:style/TextAppearance.Material.Display1" /> <LinearLayout android:id="@+id/buttons_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:id="@+id/btn_first" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/purple" android:text="@string/button_1" /> <Button android:id="@+id/btn_second" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/indigo" android:text="@string/button_2" /> <Button android:id="@+id/btn_third" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/teal" android:text="@string/button_3" /> </LinearLayout> </LinearLayout>
在前面的截图中用户接口清楚的展示了以来域一堆网格。然而,为了让用户在UI中清楚的区分独立的,这个界面在元素之间严重的缺少间隔。我们来做个简单的添加android:layout_marginTop="@dimen/spacing_medium"给LinearLayout的id是@id/buttons_container,还有添加android:layout_marginRight="@dimen/spacing_medium"给Button的id为@id/btn_first和@id/btn_second:
上面的UI看起来是很好的:它看起来是漂亮的,可读的等等。不幸的是,在隐藏一些视图的时候事情就变得有点糟糕了。的确,我们想象的正常的特性通过在@id/btn_third点击被激活,这个特性需要一些在设备是不是有效的能力(例如Google Play Services)。不让UI杂乱无章的最好方式是改变第三个Button的可见性为View.GONE:
正如被期望的,@id/btn_third不在显示,但是@id/btn_second的右边距与应用程序图标的右边距没有对齐。这个问题的主要原因是,在开始的时候margin技巧尽它的能力做了很好的工作来,坚持假设:每一个有right/top空白的视图在它的right/top有一个邻居视图。在条块中隐藏一些视图来抵挡这种约束。
处理这个问题的一个明显窍门就是手动的在java代码中改变元素的留白。这是一个真正糟糕的解决方案。另一种将使用的布局是自动的处理元素间隔。例如,GridLayout是他们中的其中之一。不幸的是,这个布局是一种使用并且不让你在元素之间指定一个指定的空白的眼中钉(只有默认的空白是有效的)。
实际上,LinearLayout已经在元素之间管理了一堆间隔。这种特性是不透明的隐藏在框架中的,但是它就像魔法一样起作用。作为LinearLayout的元素分隔器,这个窍门是用一个带有一个固有的width/height的Drawable组成:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <size android:width="@dimen/spacing_medium" android:height="@dimen/spacing_medium" /> <solid android:color="@android:color/transparent" /> </shape>
你现在能使用这种创建Drawable在元素之间作为分隔器通过设置它为LinearLayout的分割器
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:divider="@drawable/spacer_medium" android:orientation="vertical" android:padding="@dimen/spacing_medium" android:showDividers="middle"> <!-- TextView --> <LinearLayout android:id="@+id/buttons_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:divider="@drawable/spacer_medium" android:orientation="horizontal" android:showDividers="middle"> <!-- Buttons --> </LinearLayout> </LinearLayout>