活动(Activity)
活动是最容易吸引用户的地方,它是一种可以包含用户界面的组件,主要用于和用户交互。
FirstActivity
手动创建活动
新建一个project,不再选择empty activity,选择add no activity,手动创建活动
此时app/src/java/com.example.activity
为空,右击新建empty activity
,不要勾选generate layout file
和launcher activity
注:
勾选generate layout file
表示自动为activity
创建一个对应的布局文件
勾选launcher activity
表示自动将activity
设置为当前项目的主活动
勾选backwards compatibility
表示为项目启用向下兼容的模式
手动创建和加载布局
右击app/src/main/res
目录,新建directory
,在此目录下新建layout resource file
,在布局中添加一个button
,在活动中加载布局
setContentView(R.layout.布局文件名称)
在AndroidManifest
文件中注册并为程序配置主活动
<activity android: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>
标签内,通过<activity>
标签来对活动进行注册
运行结果
在活动中使用Toast
toast
是android
系统提供的一种非常好的提醒方式在程序中可以使用它将一些短小的信息通知给用户。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);
Button button1 = (Button) findViewById(R.id.button_1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(FirstActivity.this, "You clicked Button 1", Toast.LENGTH_SHORT).show();
}
});
}
定义弹出toast
的触发点,以button
为例:findViewById()
方法获取到在布局文件中定义的元素,此方法返回的是一个View
对象,通过向下转型将它转成button对象
Toast
通过静态方法makeText()
创建出一个Toast
对象,然后调用show()
将Toast
显示出来。
在活动中使用Menu
在res
目录下新建menu
文件夹,在menu
文件夹中新建menu resource file
,添加如下代码,<item>
标签用来创建具体的某一个菜单项
<item
android:id="@+id/add_item"
android:title="Add"/>
<item
android:id="@+id/remove_item"
android:title="Remove"/>
定义菜单响应事件:
(1)菜单布局完成后,回到activity中重写onCreateOptionsMenu()方法,(快捷键ctrl+O),添加如下代码
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main,menu);
return true;
}
通过getMenuInflater()方法得到MenuInflater对象,再调用它的inflate()方法就可以给当前活动创建菜单了
(2)添加菜单响应事件
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()来判断点击的菜单项,然后给每个菜单项添加逻辑处理
销毁一个活动
(1)点击返回键即可
(2)通过代码实现
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
完整代码:
// FirstActivity
package com.example.mark.activitytest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class FirstActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);
Button button1 = (Button) findViewById(R.id.button_1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(FirstActivity.this, "You clicked Button 1", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main,menu);
return true;
}
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;
}
}
SecondActivity
右击app/src/java/com.example.activity
新建SecondActivity
,勾选generate layout file
,但不要勾选launcher activity
此时SecondActivity
和对应的布局文件已经生成,修改布局文件,添加一个button
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button2"/>
</LinearLayout>
任何一个活动都需要在AndroidManifest
文件中注册,由于SecondActivity
不是主活动,因此不需要配置<intent-filter>
标签里的内容
intent
(1)显式intent
修改FirstActivity
的onClick()
方法
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivity(intent);
}
});
首先构建出一个Intent
,传入FirstActivity.this
作为上下文,传入SecondActivity.class
作为目标活动,即在FirstActivity
这个活动的基础上打开SecondActivity
这个活动,然后通过startActivity()
方法来执行这个intent
,执行结果如下
(2)隐式intent
通过在<activity>
标签下配置<intent-filter>
的内容,可以指定当前活动能够响应的action
和category
,修改AndroidManifest
如下
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="com.example.mark.activitytest.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>>
</activity>
<action>
标签指明了当前活动可以响应com.example.mark.activitytest.ACTION_START
这个action
,而<category>
标签则包含了一些附加信息,更精确地指明了当前活动能够响应的intent
中还可能带有的category
。只有<action>
和<category>
中的内容同时能够匹配上intent
中指定的<action>
和<category>
时,这个活动才能响应该intent
。
修改FirstActivity
的onClick()
方法
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.mark.activitytest.ACTION_START");
startActivity(intent);
}
});
此时使用intent
的另一个构造函数,直接将action
的字符串传了进去,表明我们想要启动能够响应com.example.mark.activitytest.ACTION_START
这个action
的活动。执行结果如下
每个intent
中只能指定一个action
,但却能指定多个category
。
调用intent
的addCategory()
方法添加一个category
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.mark.activitytest.ACTION_START");
intent.addCategory("com.example.mark.activitytest.MY_CATEGORY");
startActivity(intent);
}
});
AndroidManifest
文件在<intent-filter>
中添加category
声明
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="com.example.mark.activitytest.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.example.mark.activitytest.MY_CATEGORY" />
</intent-filter>
</activity>
(3)更多隐式intent
用法
使用隐式intent
,不仅可以启动自己程序内的活动,还可以启动其他程序内的活动,使得Android
多个应用程序之间的功能共享成为了可能
AndroidManifest
文件添加内容如下
<activity android:name=".ThirdActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
</intent-filter>
</activity>
调用系统浏览器打开网页,修改FirstActivity
的onClick()
方法
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://cn.bing.com"));
startActivity(intent);
}
});
首先指定了intent
的action
是Intent.ACTION_VIEW
,这是Android
系统内置的动作,然后通过Uri.parse()
方法,将一个网址字符解析成一个Uri
对象,再调用intent的setData()
方法将这个Uri
对象传递进去。执行结果如下
ThirdActivity
创建ThirdActivity
,保持文件内容不变,布局文件如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/button_3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button3" />
</LinearLayout>
AndroidManifest
文件修改ThirdActivity
注册信息如下
<activity android:name=".ThirdActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
</intent-filter>
</activity>
<intent-filter>
中配置了当前活动能够响应的action
是intent
,ACTION_VIEW
的常量值,而category
则毫无疑问指定了默认的category
值,另外在<data>
标签中我们通过android:scheme
指定了数据的协议必须是http
协议,这样ThirdActivity
应该就和浏览器一样,能够响应一个打开网页的intent
了。
更多隐式intent
用法
- android:scheme 用于指定数据的协议部分,如:http。
- android:host 用于指定数据的主机名部分,如:www.baidu.com。
- android:port 用于指定数据的端口部分,一般紧随在主机名之后。
- android:path 用于指定主机名和端口之后的部分。
- android:mimeType 用于指定可以处理的数据类型,允许使用通配符的方式进行指定。
调用系统拨号界面
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
}
});
首先指定了intent
的action
是Intent.ACTION_DIAL
,这是Android
系统的内置动作。然后在data
部分指定了协议是tel
,号码是10086
。执行结果如下
注:
只有<data>
标签中指定的内容和intent
中携带的data
完全一致时,当前活动才能够响应该intent
。
向下一活动传递数据(FirstActivity
传递字符串到SecondActivity
)
FirstActivity
文件如下
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String data = "hello SecondActivity";
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
intent.putExtra("extra_data",data);
startActivity(intent);
}
});
使用显式intent
的方式启动SecondActivity
,并通过putExtra()
方法传递了一个字符串。putExtra()
方法接收两个参数,第一个参数是键,用于后面从intent
中取值,第二个参数才是真正要传递的数据。
然后在SecondActivity
中将传递到数据取出,并打印出来。
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Intent intent = getIntent();
String data = intent.getStringExtra("extra_data");
Log.d("SecondActivity",data);
}
}
首先通过getIntent()
方法获取到用于启动SecondActivity
的intent
,然后调用getStringExtra()
方法,传入相应的键值,就可以得到传递的数据了。运行后,点击按钮,查看logcat
打印信息如下
返回数据给上一活动
修改FirstActivity
中按钮的点击事件如下
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivityForResult(intent,1);
}
});
startActivityForResult()
方法用于启动活动,此方法期望在活动销毁的时候能够返回一个结果给上一个活动。startActivityForResult()
接收两个参数,第一个参数是intent
,第二个参数是请求码,用于在之后的回调中判断数据的来源。
在SecondActivity
中给按钮注册点击事件
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("data_return","hello firstactivity");
setResult(RESULT_OK,intent);
finish();
}
});
setResult()
方法接收两个参数,第一个参数用于向上一个活动返回处理结果,第二个参数把带有数据的intent
传递回去,然后调用了finish()
方法来销毁当前活动
由于使用startActivityForResult()
方法启动SecondActivity
,在SecondActivity
被销毁之后会回调上一个活动的onActivityResult()
方法,所以需要在FirstActivity
中重写这个方法得到返回的数据。如下
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
switch (requestCode){
case 1:
if (resultCode == RESULT_OK){
String returnedData = data.getStringExtra("data_return");
Log.d("FirstActivity",returnedData);
}
break;
default:
}
}
运行程序,查看logcat
的打印信息如下:
通过返回键传递数据
在SecondActivty
中重写OnBackPressed()
@Override
public void onBackPressed() {
Intent intent = new Intent();
intent.putExtra("data_return","hello FirstActivity");
setResult(RESULT_OK,intent);
finish();
}
活动的生命周期
除onRestart()
之外,其他互相对应。
完整生存期:onCreate()
和onDestroy()
可见生存期:onStart()
和onStop()
前台生存期:onResume()
和onPause()
活动的启动模式
-
standard
-
singleTop
-
singleTask
-
singleInstance
在AndroidManifest.xml
中通过给android:launchMode
属性来选择启动模式