第2章 活动(Activity)

来源:互联网 发布:centos 指定ip访问ssh 编辑:程序博客网 时间:2024/05/02 01:14

第2章 活动(Activity)





通过上一章的学习,你已经成功创建了你的第一个Android项目。不过仅仅满足于此显然是不够的,是时候该学点新的东西了。作为你的导师,我有义务帮你制定好后面的学习路线,那么今天我们应该从哪儿入手呢?现在你可以想象一下,假如你已经写出了一个非常优秀的应用程序,然后推荐给你的第一个用户,你会从哪里开始介绍呢?毫无疑问,当前是从界面开始介绍了!因为即使你的程序算法再高效,架构再出色,用户根本不会在乎这些,他们一开始只会对看得到的东西感兴趣,那么我们今天的主题自然也要从看得到的入手了。


2.1 活动是什么

活动(Activity)是最容易吸引到用户的地方了,它是一种可以包含用户界面的组件,主要用于和用户进行交互。一个应用程序中可以包含零个或多个活动,但不包含任何活动的应用程序很少见,谁也不想让自己的应用永远无法被用户看到吧?

其实在上一章中,你已经和活动打过交道了,并且对活动也有了初步的认识。不过上一章我们的重点是创建你的第一个Android项目,对活动的介绍并不多,在本章中我将对活动进行详细的介绍。


2.2 活动的基本用法

到现在为止,你还没有手动创建过活动呢,因为上一章中的HelloWorldActivity是ADT帮我们自动创建的。手动创建活动可以加深我们的理解,因此现在是时候应该自己动手了。

首先,你需要再新建一个Android项目,项目名可以叫做ActivityTest,包名我们就使用默认值com.example.activitytest。新建项目的步骤你已经在上一章学习过了,不过图1.12中的那一步需要稍做修改,我们不再勾选Create Activity这个选项,因为这次我们准备手动创建活动,如图1所示。


图1


点击Finish,项目就创建完成了,这时候你的Eclipse中应该有两个项目,ActivityTest和HelloWorld。极度建议你将不相干的项目关闭掉,仅打开当前工作所需要的项目,不然我保证以后你会在这方面吃亏。最好现在就右击HelloWorld项目→Close Project。


2.2.1 手动创建活动

目前ActivityTest项目的src目录应该是空的,你应该在src目录下先添加一个包。点击Eclipse导航栏中的File→New→Package,在弹出窗口中填入我们新建项目时使用的默认包名com.example.activitytest,点击Finish。添加包之后的目录结构如图2所示。


图2


现在右击com.example.activitytest包→New→Class,会弹出新建类的对话框,我们新建一个名为FirstActivity的类,并让它继承自Activity,点击Finish完成创建。
你需要知道,项目中的任何活动都应该重写Activity的onCreate()方法,但目前我们的FirstActivity内部还什么代码都没有,所以首先你要做的就是在FirstActivity中重写onCreate()方法,代码如下所示:


public class FirstActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);}}


可以看到,onCreate()方法非常简单,就是调用了父类的onCreate()方法。当然这只是默认的实现,后面我们还需要在里面加入很多自己的逻辑。


2.2.2 创建和加载布局

前面我们说过,Android程序的设计讲究逻辑和视图分离,最好每一个活动都能对应一个布局,布局就是用来显示界面内容的,因此我们现在就来手动创建一个布局文件。
右击res/layout目录→New→Android XML File,会弹出创建布局文件的窗口。我们给这个布局文件命名为first_layout,根元素就默认选择为LinearLayout,如图3所示。


图3


点击Finish完成布局的创建。这时候你会看到如图4所示的窗口。


图4


这是ADT为我们提供的可视化布局编辑器,你可以在屏幕的中央区域预览当前的布局。在窗口的最下方有两个切换卡,左边是Graphical Layout,右边是first_layout.xml。Graphical Layout是当前的可视化布局编辑器,在这里你不仅可以预览当前的布局,还可以通过拖拽的方式编辑布局。而first_layout.xml则是通过XML文件的方式来编辑布局,现在点击一下first_layout.xml切换卡,可以看到如下代码:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ></LinearLayout>


由于我们刚才在创建布局文件时选择了LinearLayout作为根元素,因此现在布局文件中已经有一个LinearLayout元素了。那我们现在对这个布局稍做编辑,添加一个按钮,如下所示:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><Buttonandroid:id="@+id/button_1"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Button 1"/></LinearLayout>


这里添加了一个Button元素,并在Button元素的内部增加了几个属性。android:id是给当前的元素定义一个唯一标识符,之后可以在代码中对这个元素进行操作。你可能会对@+id/button_1这种语法感到陌生,但如果把加号去掉,变成@id/button_1,这你就会觉得有些熟悉了吧,这不就是在XML中引用资源的语法吗,只不过是把string替换成了id。是的,如果你需要在XML中引用一个id,就使用@id/id_name这种语法,而如果你需要在XML中定义一个id,则要使用@+id/id_name这种语法。随后android:layout_width指定了当前元素的宽度,这里使用match_parent表示让当前元素和父元素一样宽。android:layout_height指定了当前元素的高度,这里使用wrap_content,表示当前元素的高度只要能刚好包含里面的内容就行。android:text指定了元素中显示的文字内容。如果你还不能完全看明白,没有关系,关于编写布局的详细内容我会在下一章中重点讲解,本章只是先简单涉及一些。现在按钮已经添加完了,你可以点回Graphical Layout切换卡,预览一下当前布局,如图5所示。


图5


可以在中央的预览区域看到,按钮已经成功显示出来了,这样一个简单的布局就编写完成了。那么接下来我们要做的,就是在活动中加载这个布局。
重新回到FirstActivity,在onCreate()方法中加入如下代码:


public class FirstActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.first_layout);}}


可以看到,这里调用了setContentView()方法来给当前的活动加载一个布局,而在setContentView()方法中,我们一般都会传入一个布局文件的id。在第一章介绍gen目录的时候我有提到过,项目中添加的任何资源都会在R文件中生成一个相应的资源id,因此我们刚才创建的first_layout.xml布局的id现在应该是已经添加到R文件中了。在代码中去引用布局文件的方法你也已经学过了,只需要调用R.layout.first_layout就可以得到first_layout.xml布局的id,然后将这个值传入setContentView()方法即可。注意这里我们使用的R,是com.example.activitytest包下的R文件,Android SDK还会自动提供一个android包下的R文件,千万别使用错了。


2.2.3 在AndroidManifest文件中注册

别忘了前面我有说过,所有的活动都要在AndroidManifest.xml中进行注册才能生效,那么我们现在就打开AndroidManifest.xml来给FirstActivity注册吧,代码如下所示:


<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.activitytest"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="14"android:targetSdkVersion="19" /><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name=".FirstActivity"android:label="This is FirstActivity" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>


可以看到,活动的注册声明要放在<application>标签内,这里是通过<activity>标签来对活动进行注册的。首先我们要使用android:name来指定具体注册哪一个活动,那么这里填入的.FirstActivity是什么意思呢?其实这不过就是com.example.activitytest.FirstActivity的缩写而已。由于最外层的<manifest>标签中已经通过package属性指定了程序的包名是com.example.activitytest,因此在注册活动时这一部分就可以省略了,直接使用.FirstActivity就足够了。然后我们使用了android:label指定活动中标题栏的内容,标题栏是显示在活动最顶部的,待会儿运行的时候你就会看到。需要注意的是,给主活动指定的label不仅会成为标题栏中的内容,还会成为启动器(Launcher)中应用程序显示的名称。之后在<activity>标签的内部我们加入了<intent-filter>标签,并在这个标签里添加了<action android:name= "android.intent.action.MAIN" />和<category android:name="android.intent.category.LAUNCHER" />这两句声明。这个我在前面也已经解释过了,如果你想让FirstActivity作为我们这个程序的主活动,即点击桌面应用程序图标时首先打开的就是这个活动,那就一定要加入这两句声明。另外需要注意,如果你的应用程序中没有声明任何一个活动作为主活动,这个程序仍然是可以正常安装的,只是你无法在启动器中看到或者打开这个程序。这种程序一般都是作为第三方服务供其他的应用在内部进行调用的,如支付宝快捷支付服务。

好了,现在一切都已准备就绪,让我们来运行一下程序吧,结果如图6所示。


图6


在界面的最顶部是一个标题栏,里面显示着我们刚才在注册活动时指定的内容。标题栏的下面就是在布局文件first_layout.xml中编写的界面,可以看到我们刚刚定义的按钮。现在你已经成功掌握了手动创建活动的方法,让我们继续看一看你在活动中还能做哪些更多的事情。
2.2.4 隐藏标题栏
标题栏中可以进行的操作其实还是蛮多的,尤其是在Android 4.0之后加入了Action Bar的功能。不过有些人会觉得标题栏相当占用屏幕空间,使得内容区域变小,因此也有不少的应用程序会选择将标题栏隐藏掉。
隐藏的方法非常简单,打开FirstActivity,在onCreate()方法中添加如下代码:


protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE); // 必须要写在setContentView函数之前setContentView(R.layout.first_layout);}


其中requestWindowFeature(Window.FEATURE_NO_TITLE)的意思就是不在活动中显示标题栏,注意这句代码一定要在setContentView()之前执行,不然会报错。再次运行程序,效果如图7所示。


图7


这样我们的活动中就不会再显示标题栏了,看起来空间大了不少吧!
2.2.5 在活动中使用Toast
Toast是Android系统提供的一种非常好的提醒方式,在程序中可以使用它将一些短小的信息通知给用户,这些信息会在一段时间后自动消失,并且不会占用任何屏幕空间,我们现在就尝试一下如何在活动中使用Toast。
首先需要定义一个弹出Toast的触发点,正好界面上有个按钮,那我们就让点击这个按钮的时候弹出一个Toast吧。在onCreate()方法中添加代码:


protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.first_layout);Button button1 = (Button) findViewById(R.id.button_1);button1.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(FirstActivity.this, "You clicked Button 1",Toast.LENGTH_SHORT).show();}});}


在活动中,可以通过findViewById()方法获取到在布局文件中定义的元素,这里我们传入R.id.button_1,来得到按钮的实例,这个值是刚才在first_layout.xml中通过android:id属性指定的。findViewById()方法返回的是一个View对象,我们需要向下转型将它转成Button对象。得到了按钮的实例之后,我们通过调用setOnClickListener()方法为按钮注册一个监听器,点击按钮时就会执行监听器中的onClick()方法。因此,弹出Toast的功能当然是要在onClick()方法中编写了。

Toast的用法非常简单,通过静态方法makeText()创建出一个Toast对象,然后调用show()将Toast显示出来就可以了。这里需要注意的是,makeText()方法需要传入三个参数。第一个参数是Context,也就是Toast要求的上下文,由于活动本身就是一个Context对象,因此这里直接传入FirstActivity.this即可。第二个参数是Toast显示的文本内容,第三个参数是Toast显示的时长,有两个内置常量可以选择Toast.LENGTH_SHORT和Toast.LENGTH_LONG。
现在重新运行程序,并点击一下按钮,效果如图8所示。


图8



2.2.6 在活动中使用Menu

不知道你还记不记得,在上一章中创建你的第一个Android项目时,ADT在HelloWorldActivity中自动创建了一个onCreateOptionsMenu()方法。这个方法是用于在活动中创建菜单的,由于当时我们的重点不在这里,所以直接先忽略了,现在可以来仔细分析一下了。
手机毕竟和电脑不同,它的屏幕空间非常有限,因此充分地利用屏幕空间在手机界面设计中就显得非常重要了。如果你的活动中有大量的菜单需要显示,这个时候界面设计就会比较尴尬,因为仅这些菜单就可能占用屏幕将近三分之一的空间,这该怎么办呢?不用担心,Android给我们提供了一种方式,可以让菜单都能得到展示的同时,还能不占用任何屏幕的空间。
首先在res目录下新建一个menu文件夹,右击res目录→New→Folder,输入文件夹名menu,点击Finish。接着在这个文件夹下再新建一个名叫main的菜单文件,右击menu文件夹→New→Android XML File,如图9所示。


图9


文件名输入main,点击Finish完成创建。然后在main.xml中添加如下代码:

<menu xmlns:android="http://schemas.android.com/apk/res/android" ><itemandroid:id="@+id/add_item"android:title="Add"/><itemandroid:id="@+id/remove_item"android:title="Remove"/></menu>

这里我们创建了两个菜单项,其中<item>标签就是用来创建具体的某一个菜单项,然后通过android:id给这个菜单项指定一个唯一标识符,通过android:title给这个菜单项指定一个名称。
然后打开FirstActivity,重写onCreateOptionsMenu()方法,代码如下所示:

public boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.main, menu);return true;}

通过getMenuInflater()方法能够得到MenuInflater对象,再调用它的inflate()方法就可以给当前活动创建菜单了。inflate()方法接收两个参数,第一个参数用于指定我们通过哪一个资源文件来创建菜单,这里当然传入R.menu.main,第二个参数用于指定我们的菜单项将添加到哪一个Menu对象当中,这里直接使用onCreateOptionsMenu()方法中传入的menu参数。然后给这个方法返回true,表示允许创建的菜单显示出来,如果返回了false,创建的菜单将无法显示。
当然,仅仅让菜单显示出来是不够的,我们定义菜单不仅是为了看的,关键是要菜单真正可用才行,因此还要再定义菜单响应事件。在FirstActivity中重写onOptionsItemSelected()方法:


public boolean onOptionsItemSelected(MenuItem item) {switch (item.getItemId()) {case R.id.add_item:Toast.makeText(this, "You clicked Add", Toast.LENGTH_SHORT).show();break;case R.id.remove_item:Toast.makeText(this, "You clicked Remove", Toast.LENGTH_SHORT).show();break;default:}return true;}


在onOptionsItemSelected()方法中,通过调用item.getItemId()来判断我们点击的是哪一个菜单项,然后给每个菜单项加入自己的逻辑处理,这里我们就活学活用,弹出一个刚刚学会的Toast。
重新运行程序,并按下Menu键,效果如图10所示。


图10


可以看到,菜单默认是不会显示出来的,只有按下了Menu键,菜单才会在底部显示出来,这样我们就可以放心地使用菜单了,因为它不会占用任何活动的空间。然后点击一下Add菜单项,效果如图11所示。


图11



2.2.7 销毁一个活动

通过一整节的学习,你已经掌握了手动创建活动的方法,并学会了如何在活动中创建Toast和创建菜单。或许你现在心中会有个疑惑,如何销毁一个活动呢?
其实答案非常简单,只要按一下Back键就可以销毁当前的活动了。不过如果你不想通过按键的方式,而是希望在程序中通过代码来销毁活动,当然也可以,Activity类提供了一个finish()方法,我们在活动中调用一下这个方法就可以销毁当前活动了。
修改按钮监听器中的代码,如下所示:


button1.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {finish();}});

重新运行程序,这时点击一下按钮,当前的活动就被成功销毁了,效果和按下Back键是一样的。




0 0
原创粉丝点击