在Android中的网格间距

原文地址: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>

时间: 2024-10-30 04:53:36

在Android中的网格间距的相关文章

谈谈-Android中的接口回调技术

Android中的接口回调技术有很多应用的场景,最常见的:Activity(人机交互的端口)的UI界面中定义了Button,点击该Button时,执行某个逻辑. 下面参见上述执行的模型,讲述James对Android接口回调技术的理解(结合前人的知识和自己的实践). 使用一个比喻很形象地说明:客户端有个疑问打电话请教服务端,但服务端无法现场给出解答,相互之间约定:服务端一旦有答案,使用电话的方式反馈给客户端. 以上有三个主体:客户端.服务端和接口(方式). 接口回调的原理框图说明: Demo界面

关于android中事件传递和分发的一些小理解

android中 当我们的手指触摸屏幕将产生一个事件, (假设 这个过程中如果没有显示的去拦截该事件的话)   这个事件会逐级传递到视图的最底层,即使在中间某些视图会响应这个事件( 这个视图也不会去消费这个事件),     仍然是会传递到底层(底层不响应该事件),然后再由底层回传到顶层,在传回顶层的过程中 ,   原先会响应该事件的视图才会去消费这个事件 例如在左图中                                 A                               

浅谈android中仅仅使用一个TextView实现高仿京东,淘宝各种倒计时

今天给大家带来的是仅仅使用一个TextView实现一个高仿京东.淘宝.唯品会等各种电商APP的活动倒计时.最近公司一直加班也没来得及时间去整理,今天难得休息想把这个分享给大家,只求共同学习,以及自己后续的复习.为什么会想到使用一个TextView来实现呢?因为最近公司在做一些优化的工作,其中就有一个倒计时样式,原来开发的这个控件的同事使用了多个TextView拼接在一起的,实现的代码冗余比较大,故此项目经理就说:小宏这个就交给你来优化了,并且还要保证有一定的扩展性,当时就懵逼了.不知道从何处开始

Android中监听ListView滑动到底部

Android中的应用就是ListView中向下滑动加载更多的功能,不要再onScroll方法中进行判断,那样当滑动到底部的时候,可能我们需要触发点什么事件,比如加载更多.隐藏某个控件等等. 第一种方法是直接滑动到底部就触发 listview.setOnScrollListener(new OnScrollListener(){       @Override       public void onScrollStateChanged(AbsListView view, int scrollS

Android基础入门教程——8.1.3 Android中的13种Drawable小结 Part 3

Android基础入门教程--8.1.3 Android中的13种Drawable小结 Part 3 标签(空格分隔): Android基础入门教程 本节引言: 本节我们来把剩下的四种Drawable也学完,他们分别是: LayerDrawable,TransitionDrawable,LevelListDrawable和StateListDrawable, 依旧贴下13种Drawable的导图: 1.LayerDrawable 层图形对象,包含一个Drawable数组,然后按照数组对应的顺序来

Android基础入门教程——8.1.2 Android中的13种Drawable小结 Part 2

Android基础入门教程--8.1.2 Android中的13种Drawable小结 Part 2 标签(空格分隔): Android基础入门教程 本节引言: 本节我们继续来学习Android中的Drawable资源,上一节我们学习了: ColorDrawable:NinePatchDrawable: ShapeDrawable:GradientDrawable!这四个Drawable~ 而本节我们继续来学习接下来的五个Drawable,他们分别是: BitmapDrawable:Insert

Android中微信抢红包插件原理解析和开发实现

一.前言 自从去年中微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导致了.或许是网络的原因,而且这个也是最大的原因.但是其他的不可忽略的因素也是要考虑到进去的,比如在手机充电锁屏的时候,我们并不知道有人已经开始发红包了,那么这时候也是让我们丧失了一大批红包的原因.那么关于网络的问题,我们开发者可能用相关技术无法解决(当然在Google和Facebook看来的话,他们

Android中View绘制流程以及invalidate()等相关方法分析

前言: 本文是我读<Android内核剖析>第13章----View工作原理总结而成的,在此膜拜下作者 .同时真挚地向渴望了解 Android 框架层的网友,推荐这本书,希望你们能够在Android开发里学到更多的知识 . 整个View树的绘图流程是在ViewRoot.java类的performTraversals()函数展开的,该函数做的执行过程可简单概况为 根据之前设置的状态,判断是否需要重新计算视图大小(measure).是否重新需要安置视图的位置(layout).以及是否需要重绘 (d

Android中View的绘制过程 onMeasure方法简述

Android中View的绘制过程 当Activity获得焦点时,它将被要求绘制自己的布局,Android framework将会处理绘制过程,Activity只需提供它的布局的根节点. 绘制过程从布局的根节点开始,从根节点开始测量和绘制整个layout tree. 每一个ViewGroup 负责要求它的每一个孩子被绘制,每一个View负责绘制自己. 因为整个树是按顺序遍历的,所以父节点会先被绘制,而兄弟节点会按照它们在树中出现的顺序被绘制. 绘制是一个两遍(two pass)的过程:一个mea