活动(Activity)
Activity是一种包含用户界面的组件,用于和用户进行交互。
创建Activity
在使用Android Studio创建项目的时候,它会自动帮我们创建MainActivity。
其内容如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
MainActivity
类继承自AppCompatActivity
类。
onCreate
方法是重写的方法,接收一个Bundle
类型的参数savedInstanceState
,这个参数可以用来恢复Activity之前的状态。
在onCreate
方法里调用父类AppCompatActivity
的onCreate
方法。
setContentView
方法用来设置内容视图。
R.layout.activity_main
是资源文件中定义的布局文件的引用。
布局
布局文件,在res目录里有一个layout目录,展开后可以看到有一个activity_main.xml文件,其内容如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
布局
布局文件中的androidx.constraintlayout.widget.ConstraintLayout
是根布局元素,android:layout_width
和android:layout_height
是根布局的属性,设置根布局的宽度和高度,match_parent
表示布局会匹配其父容器的宽度和高度。
TextView控件
在这个布局里有一个TextView
控件,用于显示文本。android:layout_width="wrap_content"
和 android:layout_height="wrap_content"
是控件的属性,设置TextView
的宽度和高度,wrap_content
表示视图的大小会根据其内容自动调整。
android:text="Hello World!"
,设置TextView
要显示的文本。
app:layout_constraintBottom_toBottomOf="parent"
:将TextView
的底部与父布局的底部对齐。
app:layout_constraintEnd_toEndOf="parent"
:将TextView
的右边界与父布局的右边界对齐。
app:layout_constraintStart_toStartOf="parent"
:将TextView
的左边界与父布局的左边界对齐。
app:layout_constraintTop_toTopOf="parent"
:将TextView
的顶部与父布局的顶部对齐。
在这个布局里添加一个Button控件
将布局编辑器切换位Design模式,就可以预览当前的布局,也可以通过拖放的方式添加控件,将Button控件拖入进来,效果如下:
切换位Code模式,会发现xml文件中增加了如下内容:
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
tools:layout_editor_absoluteX="160dp"
tools:layout_editor_absoluteY="375dp" />
android:id="@+id/button"
:为按钮设置了一个唯一标识符。@+id/button
表示这个ID是自动生成的,并且是新的资源。button
是这个按钮的ID,可以在代码中通过这个ID来引用这个按钮。
tools:layout_editor_absoluteX="160dp"
和 tools:layout_editor_absoluteY="375dp"
:这些是设计时属性,用于在Android Studio的布局编辑器中定位按钮的位置。tools命名空间下的属性仅用于设计时,不会影响运行时的布局。layout_editor_absoluteX
和layout_editor_absoluteY
属性分别指定了按钮在布局编辑器中的X和Y坐标。
回到MainActivity,在onCreate
方法中,setContentView(R.layout.activity_main)
方法就是给当前的活动加载布局,这个方法里的参数就是这个布局文件的id。
Activity的注册
所有的活动都要在AndroidManifest.xml文件中注册才能生效,瞧一下这个文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ActivityTest"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
活动的注册声明在<application>
标签内,通过<activity>
标签来进行注册的。
在<activity>标签中
使用android:name
指定具体注册的活动,这里.MainActivity
知识省略了包名而已。
配置程序主活动
在<activity>
标签内的<intent-filter>
标签里,有<action android:name="android.intent.action.MAIN" />
和 <category android:name="android.intent.category.LAUNCHER" />
两个 标签。
action
中的.MAIN
动作用于启动一个应用程序的主界面。
category
中的LAUNCHER
类别意味着这个活动应该在设备的应用程序启动器(应用抽屉)中显示一个图标,允许用户点击图标来启动应用程序。
可以在activity
标签内添加android:label
来指定活动标题栏的内容,显示在活动最顶部,运行时可以看到。
给主活动指定的label
不仅会成为标题栏中的内容,还会成为启动器中应用程序显示的名称。
运行一下看效果
Toast
toast用于向用户显示短暂的消息或提醒,会在一段时间后自动消失。
使用Toast,首先要定义弹出Toast的出发点,正好界面里有一个按钮,可以把它定义在点击按钮的时候弹出Toast。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1 = (Button) findViewById(R.id.button);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"You click Button",Toast.LENGTH_SHORT).show();
}
});
}
点击按钮,会有如下效果:
Menu
menu就是菜单了。
在res目录下新建一个menu文件夹。
在menu文件夹里新建一个菜单文件,右击menu文件夹
->New
->Menu resource
创建完成后,在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>
在MainActivity中重写onCreateOptionsMenu
方法(快捷键Ctrl+O,然后搜索onCreateOptionsMenu)
public boolean onCreateOptionsMenu(Menu menu) {
// 通过getMenuInflater()方法得到MenuInflater对象,调用它的inflate方法给当前活动创建菜单。
// inflate()方法第一个参数是指定资源文件的,第二个参数指定菜单项
getMenuInflater().inflate(R.menu.main,menu);
return super.onCreateOptionsMenu(menu);
}
定义菜单响应事件。
在MainActivity中重写onOptionsItemSelectd()
方法
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId()==R.id.add_item){
Toast.makeText(this,"You clicked Add",Toast.LENGTH_SHORT).show();
} else if (item.getItemId()==R.id.remove_item) {
Toast.makeText(this,"You clicked Remove",Toast.LENGTH_SHORT).show();
}
return super.onOptionsItemSelected(item);
}
销毁Activity
Activity类提供了一个finish()方法,在活动中调用这个方法就可以销毁当前活动。
添加一个按钮,为按钮添加监听
<Button
android:id="@+id/finish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Finish"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.07"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3" />
Button finish_button = findViewById(R.id.finish);
finish_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
点击Finish按钮,程序退出。
Intent
使用Intent可以从主活动跳转到其他活动。
Intent是Android程序中各组件之间进行交互的一种重要方式。
显式Intent
新建Activity。
右键包名->New->Activity->Empty View Activity
在activity_second.xml里添加一个按钮
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondActivity">
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Finish"
tools:layout_editor_absoluteX="107dp"
tools:layout_editor_absoluteY="158dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
在SecondActivity中添加事件监听
Button button4 = findViewById(R.id.button4);
button4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
然后在MainActivity里添加一个按钮用来启动SecondActivity
Button intent_button = findViewById(R.id.button5);
intent_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 构建Intent,传入MainActivity.this作为上下文,传入SecondActivity.class作为目标活动
// 意图就是在MainActicity中打开SecondActivity
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
}
});
隐式Intent
不明确指出想要启动那个活动,而是指定一系列抽象的action和category,由系统分析Intent,并帮助找出合适的活动去启动。
在标签下配置的内容,可以指定当前活动能响应的action和catogory,打开AndroidManifest.xml添加代码
<activity
android:name=".SecondActivity"
android:exported="true">
<intent-filter>
<action
android:name = "com.example.ndktest.ACTION_START"/>
<category
android:name = "android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
解析:
android:exported="false"
指定该活动(Activity)是否可以被其他应用的组件(如Intent)启动。
<action android:name = "com.example.ndktest.ACTION_START"/>
指明当前活动可以响应com.example.ndk.ACTION_START
这个action,而<category>
标签则包含一些附加信息,精确指明当前的活动能够响应的Intent中还可能带有的category。
只有<action>
和<category>
中的内容能够同时匹配上Intent中指定的action和categories时,这个活动才能响应Intent。
修改MainActivity中的按钮点击事件:
Button intent_button = findViewById(R.id.button5);
intent_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 使用了Intent的另一个构造函数,直接将action的字符串传了进去,表明想要启动com.example.ndktest.ACTION_START这个action的活动。
// <category>中的android.intent.category.DEFAULT是一种默认的category,调用startActivity()方法时,会自动将category添加到Intent中。
Intent intent = new Intent("com.example.ndktest.ACTION_START");
startActivity(intent);
}
});
隐式Intent的其他使用方式
调用系统浏览器打开网页
添加一个按钮,
Button intent_button = findViewById(R.id.button);
intent_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//指定Intent的action的Intent.ACTION_VIEW,这是Android系统内置的动作,其常量值是android.intent.action.VIEW
Intent intent = new Intent(Intent.ACTION_VIEW);
//利用Uri.parse()方法将网址字符串解析成Uri对象,调用setData()将这个Uri对象传递进去
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
}
});
点击按钮后跳转百度
指定活动能够响应的数据的类型
在<intent-filter>
标签中配置一个<data>
标签,<data>
标签中配置的内容
- android:scheme。指定数据的协议部分,如http。
- android:host。指定数据的主机名部分,如www.baidu.com。
- android:port。指定数据的端口部分,一般紧随在主机名之后。
- android:path。指定主机名和端口之后的部分,如一段网址中跟在域名之后的内容。
- android:mimeType。指定可以处理的数据类型,允许使用通配符方式进行指定。
当<data>
标签中指定的内容和Intent中携带的Data完全一致时,当前活动能够响应Intet。
创建一个活动,来响应Intent
新建了一个IntetActivity,在其Layout文件里添加一个按钮
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".IntentActivity">
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
tools:layout_editor_absoluteX="119dp"
tools:layout_editor_absoluteY="159dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
然后在AndroidManifest.xml中修改IntentActivity的注册信息
<activity
android:name=".IntentActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http"/>
<data android:scheme="https"/>
</intent-filter>
</activity>
在<intent-filter>
中配置当前活动能够响应的action是Intent.ACTION_VIEW
的常量值,category中指定了默认的category值,在<data>
中通过android:scheme
指定数据协议是http协议。
运行后点击按钮
系统自动弹出了一个列表,显示能响应这个Intent的所有程序。