界面的整体布局
从这一章节开始,我们终于可以开始使用Android Studio
写代码了。
天气预报
这个应用虽然功能很简单,但是对于从来没有接触过安卓开发的人来讲,开发完成还是需要很多步骤。为了减小学习的坡度,增加开发的阶段性成就感,我将天气预报
分成2个阶段来开发,
第1阶段:暂时不考虑
Material Design
的各种限制,比如Appbar
的滑动效果,下拉刷新功能;用户点击左上角的
刷新Refresh
,应用就再次访问网络,更新天气信息的内容。第2阶段:加入
Material Design
的种种要求,比如Appbar
的滑动效果,下拉刷新功能,完善天气预报
;
我们就从第一阶段开始。
Activity与布局
Activity
几乎是每个应用必有的组件,所以任何安卓应用的开发几乎都是从Activity
开始的。
你甚至可以简单的认为,手机屏幕上能看到的整个界面,就是一个Activity
。
使用Android Studio
创建工程后,会默认为我们创建一个Activity
组件。它继承自Android SDK
的Activity
或其派生类。
class MainActivity extends Activity {
......
}
Activity
界面具体该长成什么样,是通过布局文件决定的。它位于项目的res\layout\activity_main.xml
文件中。
这个布局文件通过java源代码MainActivity.java
中onCreate()
的setContentView()
函数,设置到界面上。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
可以说xml
布局文件负责Activity
的外观容貌;java
源代码,负责Activity
的逻辑控制。java
控制着xml
中的各个元素的显示逻辑。
布局与逻辑通过setContentView()
关联在一起。
接下来,我们天气预报
界面的布局,就会在布局文件activity_main.xml
中进行。
WeatherApp
工程项目中的MainActicity
继承自AppCompatActivity
。AppCompatActivity
也是Activity
的子类,所以MainActicity
就是Activity
。这个AppCompatActivity
作用是为了兼容不同版本的Android SDK
而使用的,我们会在今后给出详细的介绍兼容性。
我们这里提到的onCreate()
函数,就是一个Activity
被运行起来后被操作系统自动调用的第一个函数,一些初始化的操作就可以在这里进行。
所以安卓开发并不是从一无所有开始写代码,而是利用系统提供的框架framework
来写程序。Activity
就是应用程序的一个框架模版。我们只需要对这个模版做一些适当的改造:继承Activity
,然后重写其中的部分方法(例如onCreate()函数)就可以了。
布局的划分
整个布局被分成了以下几个部分:
- Appbar:占据高度
56dp
; - 天气详情:显示当日的温度范围和实时天气,占据高度
240dp
;按照最终的设计,天气详情
是需要放在Appbar
里面的,但是第1阶段做了简化,所以将它单独拿出来了; - 天气预报:显示未来5日的天气预报,占据高度
96dp
; - 分割线:占据高度
8dp
; - 相关信息:当日天气的相关信息,占据所有剩余空间的高度;
Appbar的存在是由系统决定的,我们就不做修改了,主要是分配2~5
的布局空间。
布局与控件
界面设计需要先认识两类工具:控件Control
与布局Layout
。
控件Control
就是我们常常看到的按钮
滑动条
文字显示区
等等,它们就像房间里的家具,是界面设计的最小单位。为了减小界面开发的难度,SDK
会提供很多现成的界面小组件供开发者使用。布局Layout
是一个可以容纳别的布局(或者控件)的容器。它就像是一个大的房间,房间里面可以放各种家具(控件),甚至可以再隔离成更多的房间(放入别的布局)。
不过两者有很多共同的地方,例如指定它们大小、边距的方式都是一样的。
布局的边距分为margin
和padding
:
margin
-对外而言:控件或布局相对外面组件的边距叫做margin
,例如一个LinearLayout
与它相邻的另一个FrameLayout
之间的间隔。在布局或控件中,使用以下属性来定义,android:layout_margin="5dp" android:layout_marginLeft="5dp" android:layout_marginTop="5dp" android:layout_marginRight="5dp" android:layout_marginBottom="5dp"
padding
-对内而言:控件或布局为内部区域保留的边距叫做padding
,例如一个LinearLayout
与它内部的一个FrameLayout
之间的间隔,或者TextView
的边框与它内部文字之间的间隔。在布局或控件中,使用以下属性来定义,android:padding="5dp" android:paddingLeft="5dp" android:paddingTop="5dp" android:paddingRight="5dp" android:paddingBottom="5dp"
给天气预报
设计布局,就是通过选用Android SDK
中合适的布局和控件来实现的。
布局容器
整个应用的内容都是放在一个大的布局Layout
当中的。因此要首先确定这个最大的布局
。
Android SDK
提供了一个叫做LinearLayout
的布局控件。它能够让存放于其中的其他控件按照首尾顺序,一个接一个的排队摆放。正好符合我们的要求。
- 编辑
activity_main.xml
文件,删除其中原有的TextView
控件,删除RelativeLayout
中的各种padding
; - 将原来的
RelativeLayout
修改成LinearLayout
; - 给
LinearLayout
增加android:orientation
属性,其值设置成vertical
–将它包含的内容以竖直方式排列; LinearLayout
负责放置应用的整个内容,需要尽可能占用整个屏幕,因此使用match_parent
指定布局的宽度和高度。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
现在通过预览窗口,可以看到界面变成了这样,
注意:文字WeatherApp
所在的Appbar
是系统自带的,并不是activity_main.xml
中设计的。
在设置布局或者控件大小的时候,会使用它们的android:layout_width
和android:layout_height
属性,
<View
android:layout_width="match_parent"
android:layout_width="wrap_content"/>
它们的值可以设定成,
- 特定的数值:例如
5dp
。当然也可以使用除了dp
以外其他的尺寸单位,但是考虑到屏幕的像素密度不同,我们都使用dp
为单位; match_parent
:以父布局的宽度(或长度)为界,尽可能占据全部空间;wrap_content
:以子布局或控件内容的宽度(或长度)为界,尽可能少占据空间;
容器的分配
其他几个区域都占据了整个屏幕都宽度,只是高度各不相同,
区域名称 | 区域高度 | 选用控件或布局 |
---|---|---|
天气详情 | 240dp | LinearLayout |
未来5日天气预报 | 96dp | LinearLayout |
分割线 | 8dp | View |
相关信息 | 剩余的所有高度 | ListView |
View
:是安卓系统中最为基本界面的组件,所有的布局与控件都是特殊的View
(它们都是View
的子类)。这里用来作为分割线。
ListView
:是安卓SDK提供的列表控件,将数据项用列表的形式展现出来。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="240dp"
android:background="#FFFF0000">
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="96dp"
android:background="#FF00FF00">
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="8dp"
android:background="#1F000000"
/>
<ListView
android:id="@+id/weather_index_info_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0000FF">
</ListView>
</LinearLayout>
这里给ListView
布局取了一个名字-id
,叫做weather_index_info_list
。以后要使用这个ListView
的时候,可以通过这个id
找到它,例如
ListView lv = (ListView) findViewById(R.id.weather_index_info_list);
为了明显的看到各个控件与布局占据的屏幕空间分布情况,我给每个控件或布局都添加上了android:background
属性,给它们设置上了不同的颜色以示区别,后面再将它们移除。最后的效果如下,
在设计相关的章节中已经介绍过,安卓系统中的颜色数值可以用4种方式表示,
- RGB:8位RGB数值。例如红色F00,绿色0F0,蓝色00F;
- ARGB:8位RGB数值,外加8位Alpha透明度值。例如透明度为8的红色8F00,绿色80F0,蓝色800F
- RRGGBB:16位RGB数值。例如红色FF0000,绿色00FF00,蓝色0000FF;
- AARRGGBB:16位RGB数值,外加16位Alpha透明度值。例如透明度为0F的红色0FFF0000,绿色0F00FF00,蓝色0F0000FF;
代码管理
将修改的内容提交到GitHub上,这一步和之前的操作并没有任何的不同。
不过这里介绍一下你可能会遇到的意外情况:假如commit
之后push
之前,我发现自己commit
的内容有问题,要撤销上一步的commit
。这该怎么办?比如将commit
时要记录的信息写错了,要退回到commit
之前的状态。
改正的方法很简单:
- 在上一次正确的
commit
项上,点击右键; 选择
Reset Current Branch to Here...
;在弹出的菜单项上,选择
Mixed
(每种选择的效果都有对应的解释,Mixed
就是说返回commit
之前的状态,并保留修改的内容),并点击Reset
;
这样,整个commit
就回到了未被提交时的状态。检查之后再做重新的commit
。这一次就得小心仔细一些啦!
假如你不仅commit
了,而且还push
到远端的仓库中了,要恢复该怎么办呢?
答案是没办法了!之前的修改已经被记录在案了,你只能重新修改一次再提交。所以每次push
一定要注意,不然你的合作开发者一定会看到你的粗心大意。
/*******************************************************************/
* 版权声明
* 本教程只在CSDN和安豆网发布,其他网站出现本教程均属侵权。
*另外,我们还推出了Arduino智能硬件相关的教程,您可以在我们的网店跟我学Arduino编程中购买相关硬件。同时也感谢大家对我们这些码农的支持。
*最后再次感谢各位读者对安豆
的支持,谢谢:)
/*******************************************************************/