Android 开发学习笔记 2 - 活动

Just for memory.

2.1 什么是活动

活动(Activity)是一种可以包含用户界面的组件。个人感觉有点类似于 WinForm 里的窗体(Form)。

2.2 活动的基本用法

创建活动

右击包名→New→Activity→Empty Activity,根据提示完成向导即可。

项目中的任何活动都需要重写 Activity 的onCreate()方法,Android Studio 会自动完成。例如:

public class MainActivity extends AppCompatActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

如果在创建活动的时候勾选了 Generate Layout File,那么 Android Studio 会自动生成布局并添加相关代码,还会在 AndroidManifest 中注册;如果不勾选的话,那么上面代码中的 setContentView(R.layout.activity_main); 不会添加。

手动创建和加载布局

创建布局

右击 app/src/main/res 目录→New→Directory,新建 layout 目录。右击 layout→New→Layout resource file,填写名称并选择根元素即可。然后回到活动的代码,在 onCreate 方法中加入上面提到的 setContentView(R.layout.activity_main);

注册活动

之后在 AndroidManifest.xml 文件中的 <application> 节中注册活动,添加:

<activity android:name=".[ActivityName]"></activity>

<activity> 节中加入:

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

这里将这个活动注册为主活动,也就是在手机桌面点击图标进入的活动。如果没有将任何活动注册为主活动,那么在主屏幕是不会出现应用图标的。

使用 Toast

Toast 就是程序暂时显示的通知,通常以灰色为背景,出现在屏幕底部——不过这些都是可以自定义的。

以点击按钮弹出 Toast 为例,在活动的 onCreate() 方法中添加:

Button button2 = (Button) findViewById(R.id.button_2);
button2.setOnClickListener(new View.OnClickListener()
{
    @Override
    public void onClick(View v)
    {
        Toast.makeText(SecondActivity.this, data, Toast.LENGTH_SHORT).show();
    }
});

findViewById 方法用来获取定义在布局文件中的元素,传入的值取决于在布局文件中指定的 android:id 属性。然后使用 setOnClickListener() 方法为按钮注册监听器——听起来有点像在 C# 中为按钮添加事件,点击按钮就会执行监听器中的 onClick 方法,需要执行的代码就放在 onClick() 中。

下面来看看 Toast 类常用的 makeText 方法:

/**
 * @param context 在哪个对象中显示 Toast
 * @param msg 消息内容
 * @param duration 持续时间
*/
Toast.makeText(Context context, String msg, int duration)

duration 可取的值有 LENGTH_SHORTLENGTH_LONG,前者约 2.5s,后者约 3s。

使用 makeText 创建出一个 Toast 对象,然后使用 show() 方法显示。

添加菜单

在 res 目录下新建 menu 目录,在 menu 目录下新建 Menu resource file。用下面的 XML 代码设置菜单元素:

<item android:id="[id]" android:title="[title]" />

android:id 指定唯一标识符,android:title 指定显示出来的菜单项目的文字。

在活动中重写 onCreateOptionsMenu() 方法。这里可以按 Ctrl + O,然后敲前几个字母快速插入主要代码。

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

通过 getMenuInflater() 方法得到 MenuInflater 对象,向 inflate 方法传入资源文件和 Menu 对象,再让 onCreateOptionsMenu 返回 true 表示允许显示菜单。

接下来需要让菜单响应事件,重写 onOptionsItemSelected() 方法:

@Override
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)

Intent 用于在 Android 程序各个组件中进行交互,可以指定要执行的操作或者传递数据。一般用于启动活动、服务和发送广播。

显式 Intent

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

Intent 的构造参数有多个重载,这里使用的是:

/**
 * @param packageContext 启动活动的上下文
 * @param cls 想要启动的目标活动
*/
Intent(Context packageContext, Class<?> cls)

然后将构造的 Intent 传入 startActivity() 方法。这里传入 FirstActivity.this 作为上下文,SecondActivity.class 作为目标活动,即在 FirstActivity 中启动 SecondActivity,“意图”显而易见,故称显式 Intent。

隐式 Intent

相比显式 Intent,隐式 Intent 不会明确指出想要启动哪个活动,而是指定 actioncategory,交由系统分析该如何处理。

每个程序都可以指定哪个活动处理何种隐式 Intent,只需要向系统注册即可。注册过程是,向 AndroidManifest.xml 加入:

<activity
    android:name=".SecondActivity"
    android:label="This is SecondActivity">
    <intent-filter>
        <action android:name="com.example.myapplication.ACTION_START" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="com.example.myapplication.MY_CATEGORY" />
    </intent-filter>
</activity>

<action> 标签中指定当前的活动可以响应何种 action,此处为 com.example.myapplication.ACTION_START。而 <category> 中更确切地指出当前 action 该在何种环境中被响应,常用取值为:

DEFAULT:默认的执行方式,按照普通活动的执行方式执行。表示所有 Intent 都可以激活它。

HOME:设置该组件为 Home Activity,也就是作为 Launcher(桌面)。

PREFERENCE:设置该组件为 Preference。

LAUNCHER:设置该组件为在当前应用程序启动器中优先级最高的
活动 ,通常为入口 ACTION_MAIN 配合使用。

BROWSABLE:设置该组件可以使用浏览器启动。表示该活动只能用来浏览网页。

GADGET:设置该组件可以内嵌到另外的活动中。

在每个 Intent 中只能指定一个 action,但可以指定多个 category

修改 Intent 的构造函数以传递隐式 Intent:

Intent intent = new Intent("com.example.myapplication.ACTION_START");
startActivity(intent);

对于 category,除了系统定义的之外,我们还可以自定义。只需要在 <intent-filter> 中声明即可。

隐式 Intent 的其他用法

隐式 Intent 还可以用于启动其他应用的活动。这里以打开网页为例,修改点击按钮代码:

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://moefactory.com"));
startActivity(intent);

Intent.ACTION_VIEWandroid.intent.action.VIEW,用于显示用户的数据。会根据提供的数据类型来自动决定启动哪个活动。

setData() 为 Intent 传入需要处理的数据,该方法接受一个Uri类。这里使用Uri类来解析网址——值得一提的是,这里的Uri类和 C# 里的用法很类似的。

此时点击按钮,系统会调用默认浏览器打开指定的网页。当然我们也可以假装自己的程序能响应网址,这样的话需要在 <intent-filter> 中配置一个 <data>,用于指定能响应什么数据。比如上面我们指定了一个 HTTPS 的网址,那么我们就加入:

<data android:scheme="https" />

<data> 标签可以指定下列内容:

android:scheme:URI 的协议。

android:host:URI 的主机名,也就是网站中的域名或者 IP。

android:port:URI 的端口号。

android:path:URI 中除去协议、主机名、端口号之外的路径。

android:mimeType:指定可以处理的 MIME 类型。

此时运行程序,点击按钮,会提示我们选择打开方式,列表里会列出能响应该 Intent 的所有程序。

根据传入 URI 的不同,系统也会做出不同的响应。比如 URI 设置为 tel:10086 就会调用默认电话程序并将 10086 作为待拨号码。

在活动间传递数据

向下一个活动传递数据

有时候我们需要在活动之间传递数据,此时我们可以通过 Intent 的 putExtra() 方法来指定,语法如下(此处可以简单理解为键值对):

/**
 * @param name 键
 * @param value 值,可以接受多种数据类型
*/
Intent.putExtra(String name, <?> value);

之后在下一个活动中取出数据。这里要用到 getIntent() 和另一个方法。前者的语法没有参数,返回一个 Intent 类。然后,根据不同的数据类型,需要用不同的方法获得数据,比如取得字符串则用 getStringExtra(),取出布尔值则用 getBooleanExtra() 等。虽然方法名称不同,但都只需要传入一个参数 name 来指定要接受的数据即可。此处的 nameputExtra()name 键对应。

向上一个活动返回数据

首先我们需要让被启动的活动知晓需要返回数据。使用 startActivityForResult()代替 startActivity(),语法如下:

/**
 * @param intent 要传递的 Intent
 * @param requestCode 唯一请求码
*/
startActivityForResult(Intent intent, int requestCode);

在被启动的活动中,除了使用 putExtra() 来指定要返回的数据之外,还要使用 setResult() 来返回一个结果,以便于上一个活动处理。语法如下:

/**
 * @param requestCode 唯一请求码,与从上一个活动传入的值对应
 * @param intent 要传递的 Intent,此处构造其仅为返回数据
*/
setResult(int resultCode, Intent intent);

在被启动的活动销毁之后,会回调上一个活动的 onActivityResult() 方法,重写之:

@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");
			    Toast.makeText(FirstActivity.this, returnedData, Toast.LENGTH_sHORT).show();
		    }
            break;
	}
}

onActivityResult() 带有三个参数,requestCode 是被销毁的活动传入的请求码,resultCode 是在 setResult() 方法中设置的结果,data 即携带着数据的 Intent。注意区分前两者。之后可以用 switch-case 处理。

如果想要在用户按下返回键销毁活动时也能传递数据,在被启动的活动中重写 onBackPressed() 方法,加入相关代码即可。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇