• 第 8 章 深入学习UI设计


    请参考教材,全面理解和完成本章节内容... ...

    复制第七章的工程ch7,将工程目录改名为ch8。

    本章,我们开始为「陋习手记」应用添加「陋习」的记录时间和处理状态。同时我们还将设计更丰富的UI,学习到更多使用布局与组件创建UI的知识和技巧。

    8.1 升级 Crime 类

    打开Crime.java文件,新增两个实例变量。Date变量表示crime发生的时间,Boolean变量表示crime是否已得到处理,如代码清单8-1所示。

    代码清单8-1 添加更多变量到Crime(Crime.java)

    image

    代码中,使用默认的Date构造方法初始化mData变量,变量值为当前日期。该日期将作为crime默认的发生时间。(注意要import java.util. Date)

    接下来,为新增变量生成getter与setter方法,如代码清单8-2所示。

    代码清单8-2 已产生的getter与setter方法(Crime.java)

    image

    接下来,使用新组件更新fragment_crime.xml文件中的布局,然后在CrimeFragment.java文件中生成并使用这些组件。

    8.2 更新布局

    本章结束时,完成后的CrimeFragment视图应如图8-1所示。

    image

    图8-1 CriminalIntent应用界面(本章完成部分)

    提示:有时,信息的录入和显示都可以用同一个界面

    要得到图 8-1 所示的用户界面,还需为CrimeFragment的布局添加四个组件,即两个TextView组件、一个Button组件以及一个CheckBox组件。

    打开fragment_crime.xml文件,如代码清单8-3所示添加四个组件的定义。可能会出现缺少字符串资源的错误提示,我们稍后会创建这些字符串资源。

    代码清单8-3 添加新组件(fragment_crime.xml)

    image

    注意,Button组件定义中没有android:text属性。该按钮将用于显示Crime的发生日期,显示的日期文字内容将通过代码的方式进行设置。

    为什么要在Button上显示日期呢?这是在为应用的后续开发做准备。目前,crime的发生日期默认为当前日期且不可更改。第12章,我们将启用按钮组件,通过单击按钮弹出DatePicker组件以供用户设置自定义日期。

    布局定义中还有一些新的知识点可供探讨,如style及margin属性。不过首先还是先把添加了新组件的CriminalIntent运行起来吧。

    回到app esvaluesstrings.xml文件中,添加必需的字符串资源,如代码清单8-4所示。

    代码清单8-4 添加字符串资源(strings.xml)

    image

    保存修改过的文件,检查确认无拼写错误发生。

    8.3 生成并使用组件

    CheckBox需显示Crime是否已得到处理。用户勾选清除CheckBox时,Crime的mSolved变量的状态值也需得到相应的更新。

    目前,新增Button要做的就是显示Crime类中mDate变量的日期值。

    在CrimeFragment.java中,新增两个实例变量,如代码清单8-5所示。

    代码清单8-5 添加组件实例变量(CrimeFragment.java)

    image

    使用Alt+Enter,完成CheckBox相关类包的导入。

    接下来, 在onCreateView()方法中,引用新添加的按钮,如代码清单8-6所示设置它的文字属性值为crime的日期,然后暂时setEnabled(false)禁用灰掉它。

    代码清单8-6 设置Button上的文字显示(CrimeFragment.java)

    image

    禁用按钮可以保证它不响应用户的单击事件。按钮禁用后,它的外观样式灰掉了,以此表明它已处于禁用状态。等到第12章我们设置监听器时,会再次启动该按钮。

    下面要处理的是CheckBox组件,在代码中引用它并设置监听器用于更新Crime的mSolved变量值,如代码清单8-7所示。

    代码清单8-7 侦听CheckBox状态的变化(CrimeFragment.java)

    image

    使用Alt+Enter快捷键引入OnCheckedChangeListener接口的类包时, Android Studio 将提供分别定义在CompoundButton以及RadioGroup两个类中的接口以供选择。选择CompoundButton接口,因为CheckBox是CompoundButton的子类。

    如使用了代码自动补全功能,则可能会在onCheckedChanged()方法的代码上方,看到 @Overrides注解,而该注解在代码清单8-7中是不存在的。忽略此处差异,OnCheckedChangeListener接口中的方法不需要@Overrides注解。

    运行CriminalIntent应用。尝试勾选清除CheckBox状态,欣赏一下用于显示日期的禁用Button吧。

    8.4 深入探讨 XML 布局属性

    本小节,我们一起回顾一下fragment_crime.xml文件中添加的一些属性定义,并解答可能一直困扰你的组件与属性相关问题。

    8.4.1 样式、主题及主题属性

    style(样式)是XML资源文件含有用来描述组件行为和外观的属性定义。例如,下列样式资源就是用来配置组件,使其显示的文字大小大于正常值的一段代码。

    <style name="BigTextStyle">

    <item name="android:textSize">20sp</item>

    <item name="android:layout_margin">3dp</item>

    </style>

    我们可以创建自己的样式文件。将属性定义添加并保存在res/values/目录下的样式文件中,然后在布局文件中以@style/my_own_style(样式文件名)的形式引用它们。

    如下面的代码清单8-7-1所示, fragment_crime.xml文件中的两个TextView组件,每个组件都有一个引用Android自带样式文件的style属性, 该预定义样式来自于应用的主题Theme,使得屏幕上的TextView组件看起来是以列表样式分隔开的 (仔细观察8-1,标题和明细文字下面分别一条分割线) 。

    Theme是各种样式的集合。从结构上来说,主题本身也是一种样式资源,只不过它的属性指向了其他样式资源。(如Android Studio Theme)

    代码清单8-7-1 内边距属性的实际应用(fragment_crime.xml)

    <TextView
    style="?android:listSeparatorTextViewStyle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/crime_title_label"
    />
    <EditText ... />
    <TextView
    style="?android:listSeparatorTextViewStyle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/crime_details_label"
    />

    使用主题属性引用,可将预定义的应用主题样式添加给指定组件。例如,在fragment_crime.xml文件中,样式属性值?android:listSeparatorTextViewStyle的使用就是一个很好的例子。

    使用主题属性引用,相当于告知Android运行资源管理器 “在应用主题里找到名为listSeparatorTextViewStyle的属性。该属性指向其他样式资源,请将其资源的值放在这里”。

    所有Android主题都包括名为listSeparatorTextViewStyle的属性。不过,基于主题的整体观感,它们的定义稍有不同。使用主题属性引用,可以确保TextView组件在应用中拥有正确一致的界面观感。

    8.4.2 dpsp以及屏幕像素密度

    px (pixels) 是像素,就是屏幕上实际的像素点单位。

    dpi(dot per inch):屏幕像素密度,每英寸多少像素。对于屏幕来说,dpi越大,屏幕的精细度越高,屏幕看起来就越清楚。比如iphone4的视网膜级的屏幕肯定比iphone 3gs的屏幕像素密度高的多。

    dp是与密度无关,在设置边距、内边距或任何不打算按像素值指定尺寸的情况下,通常都使用dp这种单位。

    sp类似dp,主要处理字体的大小。

    HVGAdensity=160QVGAdensity=120WVGAdensity=240WQVGAdensity=120

    VGAVideo Graphics Array,即:显示绘图矩阵,相当于640×480

    HVGAHalf-size VGA;即:VGA的一半,分辨率为480×320

    QVGAQuarter VGA;即:VGA的四分之一,分辨率为320×240

    WVGAWide Video Graphics Array;即:扩大的VGA,分辨率为800×480像素;

    WQVGAWide Quarter VGA;即:扩大的QVGA,分辨率比QVGA高,比VGA低,一般是:400×240480×272

    请参考教材,理解和完成本节其他内容... ..

    8.5 使用图形布局工具

    目前为止,布局都是通过手工输入XML的方式创建的。本小节,我们将开始学习使用图形布局工具,并为CrimeFragment创建一个水平模式下使用的布局。

    设备旋转时,大多数内置布局类,如LinearLayout,都会自动拉伸和重新调整自己和自己的子类。不过,有时默认的调整并不能充分利用全部用户界面空间。

    运行CriminalIntent应用,然后旋转设备查看水平方位下的CrimeFragment布局,如图8-4所示。

    image

    图8-4 水平模式下的CrimeFragment

    要实现这个效果,需创建layout-land目录,在项目导航视图中,右键单击res目录,选择New → Directory菜单项,键入layout-land。可以看到,显示日期的按钮变成了一个长条。水平模式下,按钮如果能与check box并排放置的话会更美观些。

    要实现这个效果,需创建layout-land目录,在项目导航视图中,右键单击res目录,选择New → Directory菜单项,键入layout-land。然后将fragment_crime.xml文件复制至layout-land目录下 (有时需要将导航视图切换为Project 模式,才能看见新建的layout-land目录)。

    下面我们使用图形布局工具进行一些调整。 打开reslayout-landfragment_crime.xml文件,切换至可视化的布局设计(Design)视图如图8-5所示。

    image

    图8-5 布局设计Design视图

    在图8-5中,中间区域是布局的界面预览视图。左边是按类别组织的组件面板。右边的上半部分是组件的框架视图,它以树状排列组件,显示了组件是如何在布局中组织的;右边的下半部分是组件属性视图,在此视图中,我们可以查看并编辑框架视图中选中的组件属性。现在,参照图8-6,看看要对布局做哪些调整。

    image

    图8-6 CrimeFragment的水平模式布局

    需要的调整可分为四部分:

    • 新增一个LinearLayout组件(horizontal);
    • 编辑LinearLayout组件的属性;
    • 将Button以及CheckBox组件设置为LinearLayout的子组件;
    • 更新Button和CheckBox组件的布局参数。

    8.5.1 添加新组件

    在组件面板中选中水平的LinearLayout并将其拖曳到右边的框架视图中,如图8-7所示。

    image

    图8-7 添加到fragment_crime.xml中的LinearLayout

    也可以直接把组件从组件面板中拖曳到预览界面中,从而完成组件的添加。但由于布局组件通常是空的或者被其他视图所遮挡,所以要想获得所需的组件层级结构,很难判断到底该把组件放在预览视图的哪个部分。因此,拖曳组件到右边框架视图中是一种更为容易的方式。

    8.5.2 属性视图中编辑组件属性

    在框架视图选中新添加的LinearLayout,下面的属性视图中会显示出它的属性。

    接下来,我们需要调整LinearLayout的边距来匹配其他组件,参考图8-8完成边距设置。

    image

    图8-8 在属性视图中设置边距属性

    在预览界面底部的Text标签,切换到Text(XML)模式。可看到刚才新增边距属性的LinearLayout元素。

    8.5.3 在框架视图中重新组织组件

    接下来我们将ButtonCheckBox调整为新增LinearLayout的子组件。返回到图形布局工具,在框架视图中,选中Button后将其拖曳至LinearLayout上。

    从框架视图可以看出,Button现在是新增LinearLayout的一个子组件。对CheckBox进行同样的操作,如图8-9所示。

    image

    图8-9 ButtonCheckBox现在是新增LinearLayout的子组件

    如果子组件排列顺序不合适,可在框架视图中通过拖曳重新安排顺序。当然,也可以直接删除框架视图布局中的组件。但要当心,删除组件也会连带删除它的子组件。

    回到预览界面,CheckBox貌似不见了。这是因为Button遮挡住了它。LinearLayout考虑到了它第一个子组件(Button)的宽度属性(match_parent),并赋予了它全部空间,以至于CheckBox没有了立身之地,如图8-10所示。

    image

    图8-10 Button子组件遮住了CheckBox组件

    通过调整子组件的布局参数,可让其他子组件获得LinearLayout的平等对待。

    8.5.4 更新子组件的布局参数

    首先,在框架视图中选中crime_date日期按钮。在属性视图里,单击当前宽度值栏位,在弹出的下拉框中选择wrap_content,如图8-11-1所示。

    image

    图8-11-1 调整Button的宽度属性值为wrap_content

    既然按钮已被放置在LinearLayout里面了,因此也就不再需要边距值了。接下来,删除按钮左右16dp的边距值。如图8-11-2所示。

    image

    图8-11-2 删除按钮左右16dp的边距值

    最后,在布局参数区找到Weight栏位,设置Weight值为1。该栏位在XML文件中对应的属性是android:layout_weight,如图8-11-3所示。

    image

    图8-11-3 设置Weight值为1

    同样,在框架视图里选中crime_solved CheckBox组件,参照Button进行同样的属性调整:设置Width值为wrap_contentWeight值为1,边距值为空值。

    完成后,查看预览界面确认两个组件都能正确显现,界面效果如图8-11-4所示。

    image

    图8-11-4 修改后的界面效果图

    代码清单8-9展示了完成后的XML代码。

    代码清单8-9 图形工具创建的布局XML(layout-land/fragment_crime.xml)

    image

  • 相关阅读:
    华为精益敏捷专家:DevOps转型中的那些坑
    极致进化-敏捷进化型企业的未来畅想
    DevOps的工程化
    京东精益敏捷教练分享:敏捷助力产品创新!
    敏捷开发进度管理之燃尽图
    手把手教你进行Scrapy中item类的实例化操作
    手把手教你使用ADB卸载手机内置App软件
    手把手教你使用Python生成图灵智能小伙伴,实现工作助手/闲聊功能
    手把手教你利用Pyecharts库对IP代理数据进行数据可视化分析
    手把手教你使用Python爬取西刺代理数据(下篇)
  • 原文地址:https://www.cnblogs.com/jlxuqiang/p/4753063.html
Copyright © 2020-2023  润新知