Android-活动创建&Toast&Menu&Intent

Android系统架构

 

Android大致可分为四层架构,五块区域。

1. Linux内核层:Android系统基于Linux2.6内核,Linux内核层为Android设备的各种硬件提供底层驱动,如显示驱动、音频驱动、照相机驱动、蓝牙驱动、Wi-Fi驱动、电源管理等。

2. 系统运行库层:通过一些C/C++库为Android系统提供主要的特性支持,如SQLite库提供数据库支持,OpenGL|ES库提供3D绘图支持,Webkit库提供浏览器内核支持等。

3. 应用框架层:提供构件应用程序时可能用到的各种API,如完成Android自带的一些核心应用或开发者构建自己的应用程序所需用到的API。

4. 应用层

包括所有安装在手机上的应用程序,如系统自带的联系人、短信程序、从Google Play上下载的程序和自己开发的程序。

 

Android系统提供的应用开发特色

1. 四大组件——活动(Activity)、服务(Service)、广播接收器(Broadcast Receiver)和内容提供器(Content Provider)。

2. 丰富的系统控件。

3. 自带轻量级、运算速度极快的嵌入式关系型数据库SQLite。

4. 地理位置定位功能

5. 丰富的多媒体服务。

6. 内置多种传感器。

 

AndroidManifest.xml中有如下代码,表示对活动MainActivity进行注册:

<activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:theme="@style/AppTheme.NoActionBar">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<intent-filter>中的语句表示MainActivity是项目的主活动,在手机上点击应用图标,首先启动的就是这个活动。

活动(Activity):一种可以包含用户界面的组件,主要用于和用户进行交互,是Android应用程序的门面,凡是在应用中可见的东西都放在活动中。一个应用程序中可以包含零个或多个活动。

Activity是Android系统提供的活动基类。

 

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
}

onCreateOptionMenu()用于创建菜单。

onCreate():活动被创建时必须执行的方法。

Android程序设计遵从逻辑与视图分离,通常在布局文件中编写界面,然后在活动中引入。onCreate()中setContentView()方法给当前活动引入了一个布局。

布局.xml文件定义在/res/layout/目录下。

 

手动创建活动的步骤

1)手动创建活动.java后,为当前活动加载布局:

1. 在/res/layout/下创建布局first_layout.xml;

2. 调用R.layout.first_layout得到first_layout.xml的布局id;

3. 在活动中调用setContentView(),将布局id传入,给当前活动加载布局。

2)在AndroidManifest.xml中为活动注册

<activity
    android:name=".FirstActivity"
    android:label="This is FirstActivity">
  </activity>

android:name指定具体注册的活动,因为最外层

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.example.lily.activitytest">

package属性指定程序包名,因此前面部分可省略,直接填写.FirstActivity即可指定活动。

android:label指定活动中的标题栏内容,显示在活动顶部,也是启动器(Launcher)中应用程序显示的名称。

 

 

在<activity>标签内部加入声明

<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

使该活动成为程序主活动(点击桌面应用程序图标时首先打开该活动)。

 

隐藏标题栏的方法

在活动的onCreate()中调用requestWindowFeature(Window, FEATURE_NO_TITLE),

注意一定要在setContentView()之前执行。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.first_layout);
}

 

在活动中可以使用Toast,将一些短小的信息通知给用户,在一段时间后自动消失,并且不会占用任何屏幕空间。

例:使点击按钮button1作为Toast触发点。在onCreate()中加入:

Button button1 = (Button)findViewById(R.id.button_1);
button1.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        Toast.makeText(FirstActivity.this, "You clicked Button 1", Toast.LENGTH_SHORT).show();
    }
});

传入R.id.button_1(由layout.xml中按钮的android:id属性指定),通过findeViewById()获取在布局文件中定义的元素返回View对象,向下转型得到按钮实例。

调用setOnClickListener为按钮注册监听器,在onClick()方法中编写弹出Toast的功能。

Toast使用方法:通过makeText()创建Toast对象,调用show()显示Toast。

makeText()的参数:Context对象,直接传入FirstActivity.this;Toast显示的文本内容;Toast显示时长(可选内置常量Toast.LENGTH_SHORT和Toast.LENGTH_LONG。

 

在活动中使用Menu,点击Menu可以展示菜单。

在res目录下创建menu文件夹,新建main.xml,添加代码:

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

<item>创建具体菜单项,android:id指定唯一标识符,android:title指定菜单项名称。

 

在活动代码中重写onCreateOptionMenu()方法:

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

getMenuInflater()得到MenuInflater对象,调用inflate()方法给当前活动创建菜单。

Inflate()第一个参数指定通过哪个资源文件创建菜单,传入R.menu.main,第二个参数指定菜单项将添加到哪个Menu对象中,传入onCreateOptionMenu中传入的menu参数。

返回true表示允许创建的菜单显示出来。

 

在活动中重写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;
}

调用item.getItemId()判断点击的是哪个菜单项,给每个菜单项加入逻辑处理。

 

销毁活动:在活动中调用finish()方法。

 

Intent:Android程序中各组件之间进行交互的一种方式,可指明当前组件想要执行的动作、在不同组件之间传递数据。一般用于启动活动、启动服务、发送广播等场景。

1. 使用显示Intent启动另一活动

新建布局second_layout.xml和活动SecondActivity并重写onCreate()方法;

在AndroidManifest.xml中为SecondActivity注册;

<activity android:name=".SecondActivity">
</activity>

由于SecondActivity不是主活动,不需要配置<intent-filter>标签的内容

修改FirstActivity中button1的点击事件:

button1.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
       Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
        startActivity(intent);
    }
});

Intent构造函数Intent(Context packageContext, Class<?> cls)接收参数为启动活动的上下文和想要启动的目标活动

这里传入FirstActivity.this作为上下文,传入SecondActivity.class作为目标活动构建一个Intent,通过startActivity()方法执行Intent。

 

2. 使用隐式Intent

隐式Intent指定一系列更为抽象的action和category等信息,交由系统分析Intent找出响应该隐式Intent的活动来启动。

在AndroidManifest.xml中为SecondActivity配置<intent-filter>的内容:

<activity android:name=".SecondActivity">
    <intent-filter>
        <action android:name="com.example.lily.activitytest.ACTION_START" />
        <category android:name="android.intent.category.DEFAULT" />
     </intent-filter>
</activity>

指定当前活动能够响应的action和category,只有<action>和<category>中的内容能够同时匹配上Intent中指定的action和category时,活动才能响应该Intent。

 修改FirstActivity中按钮点击事件:

button1.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
       Intent intent = new Intent("com.example.lily.activitytest.ACTION_START");
        startActivity(intent);
    }
});

传入action的字符串构造一个Intent,表明想要启动能够响应该action的活动;

而android.intent.category.DEFAULT是一种默认的category,在调用startActivity()时自动将该category添加到intent中;

运行程序后点击按钮,因为<action>和<category>同时匹配,成功通过隐式Intent启动SecondActivity。

 

每个Intent只能指定一个action,但能指定多个category,在FirstActivity中添加新的category:

intent.addCategory("com.example.lily.activitytest.MY_CATEGORY");

要使活动响应该intent,需要在AndroidManifest.xml中SecondActivity的<intent-filter>标签里为新增的category添加声明:

<category android:name="com.example.lily.activitytest.MY_CATEGORY" />

运行程序后点击按钮,<action>和<category>同时匹配,成功通过隐式Intent启动SecondActivity。

 

通过Intent调用系统浏览器打开网页

修改FirstActivity中的按钮点击事件:

button1.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent=new Intent(Intent.ACTION_VIEW);
        intent.setData(Uri.parse("http://www.baidu.com"));
        startActivity(intent);
    }
});

指定Intent的action为Intent.ACTION_VIEW,是Andorid系统内置动作,常量值为android.intent.action.VIEW;

通过Uri.parse()将传入的网址字符串解析为一个Uri对象,Uri对象指定当前Intent正在操作的数据;

调用Intent的setData()方法,将Uri对象传入;

运行程序在FirstActivity点击按钮可调用系统浏览器打开网页。

 

可在<intent-filter>标签中配置<data>标签,用于精确指定当前活动能够响应的数据类型,只有<data>标签中指定的内容和Intent标签中携带的Data完全一致时活动才能响应该Intent。<data>标签主要可配置以下内容:

android:scheme 用于指定数据协议部分,如http

android:host 用于指定数据的主机名部分,如www.baidu.com

android:port用于指定数据的端口部分,一般紧随主机名后

android:path 用于指定主机名和端口之后的部分,如一段网址中跟在域名之后的内容

android:mimeType 用于指定可以处理的数据类型,允许使用通配符的方式指定

 

建立能相应打开网页的Intent的活动

添加third_layout.xml,活动ThirdActivity.java;

在AndroidManifest.xml中为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>

在ThirdActivity的<intent-filter>中配置当前活动能够响应的action是Intent.ACTION_VIEW的常量值,配置category为指定的默认值,<data>通过android:scheme指定数据协议为http协议,这样ThirdActivity就和浏览器一样能够响应一个打开网页的Intent。

运行程序:

系统弹出列表显示可响应该Intent的所有程序,点击Browser打开浏览器并显示百度主页,点击ActivityTest启动ThirdActivity。

 

 

指定tel协议在程序中调用系统拨号界面

修改FirstActivity中按钮点击事件:

button1.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent=new Intent(Intent.ACTION_DIAL);
        intent.setData(Uri.parse("tel:10086"));
        startActivity(intent);
    }
});

指定action为Intent.ACTION_DIAL(安卓内置动作)

修改AndroidManifest.xml中FirstActivity<intent-filter>中的data标签,指定tel协议:

<data android:scheme="tel" />

运行程序点击button1可启动拨号10086

 

 

通过Intent向下一个活动传递数据

修改FirstActivity中按钮点击事件:

button1.setOnClickListener(new 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);
    }
});

使用显示Itent启动SecondActivity,调用putExtra方法在Intent中暂存字符串数据,接收参数1为键(用于后面从Intent中取值),参数2为需要传递的数据;

在SecondActivity中将传递的数据取出并打印:

Intent intent = getIntent();
String data = intent.getStringExtra("extra_data");
Log.d("SecondActivity", data);

调用getIntent()获取启动SecondActivity的Intent,再调用getStringExtra()获取传递的字符串数据(整形数据用getIntExtra(),布尔型用getBooleanExtra());

运行程序点击button1跳转到SecondActivity,Logcat打印字符串信息。

通过Intent返回数据给上一个活动

修改FirstActivity中的按钮点击事件:

button1.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
        startActivityForResult(intent, 1);
    }
});

调用startActivityForResult启动SecondActivity,startActivity()传入参数1为Intent,参数2为唯一值的请求码(用于回调中判断数据来源);

为SecondActivity注册按钮点击事件并添加返回数据逻辑:

Button button2 = (Button) findViewById(R.id.button_2);
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();
    }
});

构建Intent用于传递数据;

调用setResult()用于向上一个活动返回数据,setResult()传入参数1为返回处理结果(一般为RESULT_OK或RESULT_CANCELED),参数2为带有数据的intent;

调用finish()销毁当前活动,回调到启动该活动的上一个活动的onActivityResult();

在FirstActivity中重写onActivityResult(),得到返回的数据:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch(requestCode) {
        case 1:
            if(resultCode == RESULT_OK) {
                String returnedData = data.getStringExtra("data_return");
                Log.d("FirstActivity",returnedData);
            }
            break;
        default:
    }
}

onActivityResult传入参数1为启动活动时传入的请求码,参数2为返回的处理结果,参数3为携带返回数据的Intent;

各种活动返回的数据都会回调onActivityResult,所以首先要检查requestCode判断数据来源;

确定数据来源后通过resultCode判断处理结果;

如果处理成功,从data中取出数据并打印。

运行程序,在FirstActivity点击button1会打开SecondActiity,点击button2回到FirstActivity,LogCat打印字符串信息。

 

如果用户通过Back键回到FirstActiviy

重写SecondActivity的onBackPressed方法:

@Override
public void onBackPressed() {
    Intent intent= new Intent();
    intent.putExtra("data_return", "Hello FirstActiviy");
    setResult(RESULT_OK, intent);
    finish();
}

运行程序,在FirstActivity点击button1打开SecondActivity,点击Back键回到FirstActivity,LogCat打印字符串信息。

posted @ 2017-08-04 16:09  丹尼尔奥利瓦  阅读(376)  评论(0编辑  收藏  举报