2.2.2
项目中生成的任何资源都会在R文件下生成一个相应的资源id。
2.2.3在AndroidManifest.xml文件中注册
活动的声明注册要放在<application>标签内,这里是通过<activity>标签来对活动进行注册的。为程序配置主活动:在<activity>标签内加入<intent-fliter>这两行。
如果只是注册了活动,而没有声明任何一个活动作为主活动,这个程序仍然是可以正常安装的,只是无法在启动器中看到或打开这个程序。这种程序一般都是作为第三方服务供其他应用程序在内部进行调用的,如支付宝快捷支付服务。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.administrator.activitytest">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".FirstActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
使用android:label指定活动中标题栏的内容,标题栏是显示在活动最顶部的。需要注意的是,给主活动指定的label不仅会成为标题栏中的内容,还会成为
启动器(Launcher)中
应用程序显示的名称。
2.2.4 使用Toast
public class FirstActivity extends AppCompatActivity {
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(FirstActivity.this,"You Clicked Button 1",Toast.LENGTH_SHORT).show();
}
});
}
}
findViewById()的返回值是View类型,所以需要向下转型成Button.
通过静态方法makeText()创建出一个Toast对象,然后调用show()显示出来。
makeText():第一个参数是一个Context对象,
由于活动本身就是一个Context对象,所以传入FirstActivity.this
第二个参数是Toast显示的文本内容,第三个参数是Toast显示的时长,有两个内置常量可以选择:
Toast
.
LENGTH_SHORT和
Toast
.
LENGTH_LONG
2.2.5在活动中显示Menu
1.在res目录下新建一个menu文件夹。接着在这个文件夹下新建一个名叫main的menu菜单 ( New --> Menu resource File )
main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/add_item"
android:title="add"/>
<item android:title="remove"
android:id="@+id/remove_item"/>
</menu>
<item>标签用来创建具体的某一个菜单项,然后通过android:id 给这个菜单项指定一个唯一的标识符,通过android:title给这个菜单项指定一个名称
2.在FirstActivity中重写
onCreateOptionsMenu()方法(重写方法用Ctrl + O)
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main,menu);
return true;
}
通过getMenuInflater可以得到MenuInflater对象,再调用它的inflater()方法创建菜单
inflater():第一个参数用于指定我们通过哪个资源文件来创建菜单,第二个参数用来指定我们的菜单项将添加到哪一个Menu对象当中,这里直接使用onCreateOptionsMenu()传入的menu参数。
然后给这个方法返回true,表示允许创建的菜单返回出来,如果返回false,创建的菜单将无法显示。
3.重写
onOptionsItemSelected()方法,定义菜单响应事件
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.add_item:
Toast.makeText(FirstActivity.this,"Add Menu",Toast.LENGTH_SHORT).show();break;
case R.id.remove_item:
Toast.makeText(FirstActivity.this,"Remove Menu",Toast.LENGTH_SHORT).show();
break;
default:
}
return true;
}
通过调用item.getItemId()来判断我们点击的是哪一个菜单项
2.2.6 销毁一个活动
调用finish() 或者按下Back键。注意:按home键不会销毁活动,只会使活动进入停止状态
2.3 使用Intent
Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent一般可被用于启动活动、启动服务以及发送广播等场景。
Intent大致可分为两种:显式Intent和隐式Intent
Intent(Context packageContext , Class<?> cls):第一个参数
Context
要求提供一个启动活动的上下文,第二个参数Class则是指定想要启动的目标活动,通过这个构造函数就可以构建出Intent的“意图”。
将构建好的Intent传入startActivity()就可以启动目标活动。
2.3.2使用隐式Intent
隐式Intent并不明确指出我们想要启动哪一个活动,而是指定了一系列更抽象的action和category等信息,然后交由系统去分析这个Intent,并帮我们找出合适的活动去启动。
1.在AndroidManifest.xml中指定SecondActivity能响应的action和category
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="com.example.administrator.activitytest.ACTION_START"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
只有<action>和<category>中的内容同时能匹配上Intent中指定的action和category时,这个活动才能响应该Intent
2.修改FirstActivity中的按钮点击事件
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.administrator.activitytest.ACTION_START");
startActivity(intent);
}
});
Intent (String action):传入action的字符串。
此时并没有指定category,因为
android.intent.category.DEFAULT是一种默认的category,在调用startActivity()方法的时候会自动将这个category添加到Intent中。如果在
AndroidManifest.xml中不指定这个category
<category android:name="android.intent.category.DEFAULT"/>
也能启动SecondActivity
每个Intent中只能指定一个action,但却能指定多个category
3.在Intent中增加一个自定义的category。注意要在
AndroidManifest.xml中声明
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="com.example.administrator.activitytest.ACTION_START"/>
<category android:name="com.example.administrator.activitytest.MY_CATEGORY"/>
</intent-filter>
</activity>
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.administrator.activitytest.ACTION_START");
intent.addCategory("com.example.administrator.activitytest.MY_CATEGORY");
startActivity(intent);
}
});
2.3.3 更多隐式Intent的用法
使用隐式Intent,我们不仅可以启动自己程序内的活动,还可以启动其他程序的活动
调用系统浏览器打开一个网页
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
// intent.setData(Uri.parse("tel:10086"));
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
}
});
这里我们首先指定了Intent的action是
Intent.ACTION_VIEW,这是一个Android系统内置的动作,其常量值为 android.intent.action.VIEW,
会根据用户的数据类型打开相应的Activity。(比如传“tel:12345”打开拨号,传
”
http://....“ 打开浏览器)
调用拨号界面还可以用内置动作Intent.ACTION_DIAL
这里我们通过Uri.parse()将网址字符串解析成一个Uri对象,再调用Intent的setData()方法将这个Uri对象传递进去。setData()接收一个Uri对象,主要用于指定当前Intent正在操作的数据,而这些数据通常都是以字符串的形式传到Uri.parse()方法中解析的。
还可以在<intent-filter>标签中再配置一个<data>标签,用于更精确的指定当前活动能够响应什么类型的数据。
只有<data>标签中指定的内容和Intent中携带的Data完全相同时,当前活动才能响应该Intent。
在上面浏览器示例中,只需要指定<data>中android:scheme 为http就可以响应所有的http协议的Intent了
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="http" />
</intent-filter>
</activity>
注意这个默认的category值不能省略
<category android:name="android.intent.category.DEFAULT"/>
2.3.4向下一个活动传递数据
Tip: putExtra():第一个参数是键,第二个参数是要传递的数据 getxxxExtra():参数是键
通过getIntent()方法获取到用于启动当前Activity的Intent
1.FirstActivity
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String data = "FirstActivity start ThreeActivity";
Intent intent = new Intent(FirstActivity.this,ThreeActivity.class);
intent.putExtra("mykey",data);
startActivity(intent);
}
});
2.ThreeActivity
public class ThreeActivity extends AppCompatActivity {
private static final String TAG="ThreeActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_three);
Intent intent = getIntent();
String getData =intent.getStringExtra("mykey");
Log.d(TAG, getData);
}
}
2.3.5返回数据给上一个活动
Tip :
startActivityForResult(Intent intent ,int requestCode):第二个参数是请求码,用于在之后的回调中判断数据的来源,
请求码只要唯一就可以了
setResult(int resultCode,Intent data)//
向上一个活动返回数据:第一个参数用于向上一个活动返回处理结果,一般只使用
RESULT_OK和RESULT_CANCELED,第二个参数把带有数据的Intent传回去。一般之后还会调用finish()来销毁当前活动。
onActivityResult(
int requestCode, int resultCode, Intent data
):第一个参数
requestCode,即我们在启动活动
startActivityForResult()
时传入的请求码。第二个参数
resultCode,即我们在返回数据
setResult()
时传入的处理结果。第三个参数
data,即携带着返回数据的
Intent
1.在FirstActivity中调用startActivityForResult()
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this,ThreeActivity.class);
startActivityForResult(intent,1);
}
});
2.当在
ThreeActivity中按下Back键时,会执行onBackPressed()中的代码。可以在这里添加返回数据的逻辑
public void onBackPressed() {
String data = "ThreeActivity return to FirstActivity ";
Intent intent = new Intent();
intent.putExtra("mytestkey",data);
setResult(RESULT_OK,intent);
super.onBackPressed();//或者调用finish()
}
3.在
ThreeActivity被销毁之后会回调上一个活动的onActivityResult()方法,因此我们需要在
FirstActivity中重写这个方法来得到返回的数据
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode){
case 1:
if(resultCode==RESULT_OK){
String redata = data.getStringExtra("mytestkey");
Log.d(TAG, redata);
}
break;
default:
}
super.onActivityResult(requestCode, resultCode, data);
}
由于在一个 活动中可能调用startActivityForResult()方法去启动很多不同的活动,每一个活动返回的数据都会回调到onActivityResult()中,因此我们要先检查
requestCode的值来判断数据来源。再通过
resultCode的值判断处理结果是否成功,最后从
data取值进行操作。
2.4 2.5 Activity的生命周期和启动模式 见上一篇博客