原文:10天学安卓-第三天
经过第二天的学习,我们正确的调用了百度天气API,将天气信息显示到了界面上,做到这一步,我们的工作就算是完成1%了,剩下99%的工作就需要不断的润色这个未成形的APP了。
最首要的就是,我们要把那么一大堆字符转换为普通用户可以轻松理解的界面,那么我们来学习一下Android里面的界面布局。
打开res/layout/activity_main.xml文件,切换到Layouts选项卡,可以看到里面有许多项目,GridLayout、LinearLayout、RelativeLayout等,这些都代表什么类型的布局呢?
理论知识
总体来说,Android界面布局分为5中,分别为LinearLayout(线性布局)、RelativeLayout(相对布局)、FrameLayout(框架布局)、TableLayout(表格布局)、GridLayout(网格布局),下面逐一简单介绍一下。
LinearLayout(线性布局)
LinearLayout使得布局内部的元素以水平(horizontal)或者垂直(vertical)的方式排成一行,
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="第一个文本" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="第二个文本" /> </LinearLayout>
其中,android:orientation指定布局内部元素的排列方式,如果没有此项设置,默认为水平排列。
设置好排列方式之后的效果分别如下:
RelativeLayout(相对布局)
RelativeLayout使得布局内部的元素以相对于容器、其他元素的位置排列,
<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="match_parent" > <TextView android:id="@+id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:text="第一个文本" /> <TextView android:id="@+id/text2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/text1" android:layout_toRightOf="@id/text1" android:text="第二个文本" /> </RelativeLayout>
这个布局定义了第一个文本位于布局的左上角,第二个文本在第一个文本的右下。
FrameLayout(框架布局)
FrameLayout使得布局内部的元素按照层次堆叠在左上角,后添加的元素会覆盖前面的元素。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="60sp" android:background="#00ff00" android:text="第一个文本" /> <TextView android:id="@+id/text2" android:layout_width="wrap_content" android:textSize="40sp" android:layout_height="wrap_content" android:background="#ff00ff" android:text="第二个文本" /> </FrameLayout>
这样第二个文本会覆盖在第一个文本的上面,
TableLayout(表格布局)
TableLayout使得布局内部的元素以行和列的形式排列,每一行都是一个TableRow或者一个普通的View,
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:stretchColumns="1"> <TableRow> <TextView android:layout_column="1" android:text="Open..." android:padding="3dip" /> <TextView android:text="Ctrl-O" android:gravity="right" android:padding="3dip" /> </TableRow> <TableRow> <TextView android:layout_column="1" android:text="Save..." android:padding="3dip" /> <TextView android:text="Ctrl-S" android:gravity="right" android:padding="3dip" /> </TableRow> <View android:layout_height="2dip" android:background="#FF909090" /> <TableRow> <TextView android:layout_column="1" android:text="Quit" android:padding="3dip" /> </TableRow> </TableLayout>
这个布局有四行,1、2、4行是TableRow,各有数目不同的文本,第3行是一个普通的View,
GridLayout(网格布局)
GridLayout使得布局内部的元素以行、列、单元格的形式排列,
<?xml version="1.0" encoding="utf-8"?> <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:rowCount="5" android:columnCount="4" > <Button android:text="1"/> <Button android:text="2"/> <Button android:text="3"/> <Button android:text="/"/> <Button android:text="4"/> <Button android:text="5"/> <Button android:text="6"/> <Button android:text="×"/> <Button android:text="7"/> <Button android:text="8"/> <Button android:text="9"/> <Button android:text="-"/> <Button android:layout_columnSpan="2" android:layout_gravity="fill" android:text="0"/> <Button android:text="."/> <Button android:layout_rowSpan="2" android:layout_gravity="fill" android:text="+"/> <Button android:layout_columnSpan="3" android:layout_gravity="fill" android:text="="/> </GridLayout>
这里定义了一个简单的计算器布局,
其他布局
除了以上5种主要的布局,还有一些第三方的布局,可以让你方便的实现一些比较酷炫的效果,例如DrawerLayout(左滑弹出菜单)、SwipeBackLayout(左滑返回)等,这些知识需要有一定的开发经验之后慢慢摸索。
小结
以上是简单介绍了一下各种布局的使用方式,具体各个布局还有很多的属性,活用这些属性才会制作出实用的界面,这些属性要靠大家在不断的学习中慢慢掌握。
在所有的布局里面,我这里推荐大家使用RelativeLayout。如果使用其他布局,可能需要嵌套比较多的层级才可以实现的界面,通常使用RelativeLayout会比较方便,而如果层级较多,对于界面的展示会需要耗费比较多的内存,所有我这里推荐使用RelativeLayout。
好了,大家辛苦了,先休息一下吧,下面我们就要使用RelativeLayout来做我们的第一个界面了。
天气界面
让我们回到我们的项目,打开res/layout/activity_main.xml文件,删掉TextView,添加一个新的控件-ListView。
然后切换到代码模式,确认一下ListView的属性,
<ListView android:id="@+id/weather_list" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" > </ListView>
这里的属性说明的是这个ListView宽度撑满界面,高度自适应,水平居中并且垂直居中,它的id是weather_list,大家还记得id的作用吧,它使得这个控件在代码中可以被找到并使用。
话说这个ListView是干什么用的?
当然是显示天气了。还以北京的天气为例,http://api.map.baidu.com/telematics/v3/weather?location=%E5%8C%97%E4%BA%AC&output=json&ak=YknGmxIoPugT7YrNrG955YLS, 这个链接返回的数据是:
{ error: 0, status: "success", date: "2015-01-19", results: [ { currentCity: "北京", pm25: "80", index: [ { title: "穿衣", zs: "冷", tipt: "穿衣指数", des: "天气冷,建议着棉服、羽绒服、皮夹克加羊毛衫等冬季服装。年老体弱者宜着厚棉衣、冬大衣或厚羽绒服。" }, { title: "洗车", zs: "较适宜", tipt: "洗车指数", des: "较适宜洗车,未来一天无雨,风力较小,擦洗一新的汽车至少能保持一天。" }, { title: "旅游", zs: "适宜", tipt: "旅游指数", des: "天气较好,同时又有微风伴您一路同行。虽会让人感觉有点凉,但仍适宜旅游,可不要错过机会呦!" }, { title: "感冒", zs: "少发", tipt: "感冒指数", des: "各项气象条件适宜,无明显降温过程,发生感冒机率较低。" }, { title: "运动", zs: "较适宜", tipt: "运动指数", des: "天气较好,但考虑气温较低,推荐您进行室内运动,若户外适当增减衣物并注意防晒。" }, { title: "紫外线强度", zs: "最弱", tipt: "紫外线强度指数", des: "属弱紫外线辐射天气,无需特别防护。若长期在户外,建议涂擦SPF在8-12之间的防晒护肤品。" } ], weather_data: [ { date: "周一 01月19日 (实时:3℃)", dayPictureUrl: "http://api.map.baidu.com/images/weather/day/qing.png", nightPictureUrl: "http://api.map.baidu.com/images/weather/night/qing.png", weather: "晴", wind: "微风", temperature: "-5℃" }, { date: "周二", dayPictureUrl: "http://api.map.baidu.com/images/weather/day/duoyun.png", nightPictureUrl: "http://api.map.baidu.com/images/weather/night/duoyun.png", weather: "多云", wind: "微风", temperature: "5 ~ -2℃" }, { date: "周三", dayPictureUrl: "http://api.map.baidu.com/images/weather/day/qing.png", nightPictureUrl: "http://api.map.baidu.com/images/weather/night/qing.png", weather: "晴", wind: "北风3-4级", temperature: "5 ~ -6℃" }, { date: "周四", dayPictureUrl: "http://api.map.baidu.com/images/weather/day/qing.png", nightPictureUrl: "http://api.map.baidu.com/images/weather/night/qing.png", weather: "晴", wind: "微风", temperature: "6 ~ -5℃" } ] } ] }
这是json格式的数据,其中[weather_data]这个节点就是当前以及接下来4天的天气,一共是5条数据,这样标准的列表数据当然是使用ListView控件来显示了。
那么,如何进行呢?
赵本山老师教过我们,总共分三步,
1. 取得数据
2. 做成界面
3. 把数据显示到界面上
那么,数据已经取得了,下面就进行第二步,做成界面。
ListView
如何使用ListView?在Android的设计中,这里就是一个标准的代码分离的方案,ListView作为一个容器使用,而其中的每一项单独使用另外的View来实现,那么,具体来说我们需要做些什么?
不要着急,慢慢来。
邮件点击res/layout目录,选择New > Android XML File,在弹出框中按照下图所示进行填写,
然后点击Finish,就切换到了我们新建的这个视图了,这个视图将定义ListView中每一项都显示什么内容。根据百度的数据,我们的这个天气预报APP可以显示日期、天气、风、温度以及两个分别代表白天晚上的天气图片,那么我们就可以开始行动了,先添加4个TextView和1个ImageView,位置可以随便放置。需要注意的是在添加ImageView的时候,会弹出选择图片资源的对话框,我们就选中默认的ic_launcher就好了。
这些做好之后,看看我们的界面是什么样子。不管怎么说,我的是这样子的:
很那看是不是,还是那句话,不着急,我们来调整一下。
选中左上角的TextView,然后注意图中红框部分,我们将在这里设置它的属性,包括宽度、位置、字体等,大家练习一下吧,试着设置一下各个项目,看看都会有什么反应。
嗯,先来看看我调整后的界面吧。
说不上好看,也算是比较标准的列表项目了。分享一下我的代码吧:
<?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="wrap_content" android:padding="10dp" > <TextView android:id="@+id/item_date" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="日期" android:textColor="#000000" android:textSize="18sp" /> <TextView android:id="@+id/item_weather" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/item_date" android:layout_marginTop="5dp" android:text="天气" android:textColor="#000000" android:textSize="14sp" /> <TextView android:id="@+id/item_wind" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/item_date" android:layout_marginLeft="5dp" android:layout_marginTop="5dp" android:layout_toRightOf="@id/item_weather" android:text="风" android:textColor="#000000" android:textSize="14sp" /> <TextView android:id="@+id/item_temperature" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/item_date" android:layout_marginLeft="5dp" android:layout_marginTop="5dp" android:layout_toRightOf="@id/item_wind" android:text="温度" android:textColor="#000000" android:textSize="14sp" /> <ImageView android:id="@+id/item_picture" android:layout_width="40dp" android:layout_height="40dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:src="@drawable/ic_launcher" /> </RelativeLayout>
你可以直接使用我的设置,这样很方便。 ^_^
嗯,到这里,三步里面的第二步也完成了,好辛苦啊,休息休息。
通过今天的折腾,我们的界面又变成不显示任何内容的了,不要担心,我们明天继续。
附件是本次的工程文件,点击下载。
此系列文章系本人原创,如需转载,请注明出处 www.liuzhibang.cn