文章目录
第一章常用布局和前端页面组件
一,常用布局
1. 线性布局(Linear Layout)
名词解释: 线性布局是一种按照水平或垂直方向排列子视图的布局方式。它允许开发者按照线性顺序排列视图,可以设置视图的权重以及对齐方式。
常用组件、标签和代码样例:
- 组件:TextView(文本视图)、EditText(输入框)、Button(按钮)、ImageView(图片视图)
- 标签:android:orientation(设置布局方向)、android:layout_weight(设置视图的权重)
示例代码:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, World!" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me" />
</LinearLayout>
2. 相对布局(Relative Layout)
名词解释: 相对布局允许开发者通过指定子视图相对于其他视图或父视图的位置来进行布局。
常用组件、标签和代码样例:
- 组件:TextView(文本视图)、EditText(输入框)、Button(按钮)、ImageView(图片视图)
- 标签:android:layout_below(视图在另一个视图的下方)、android:layout_alignParentTop(视图与父视图顶部对齐)
示例代码:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, Relative Layout!" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:layout_below="@id/textView"
android:layout_marginTop="10dp"/>
</RelativeLayout>
3.约束布局(ConstraintLayout)
在 Android 开发中,约束布局(ConstraintLayout)是一种强大的布局容器,用于创建灵活和响应式的用户界面。它可以帮助开发者以声明性方式定义视图之间的关系,而不需要嵌套多个布局层次结构。下面我将解释一下约束布局的特点和使用方法:
特点
-
强大的约束关系:约束布局使用约束来定义视图之间的关系,包括相对位置、边距、尺寸等。通过设置视图之间的约束条件,可以实现各种复杂的布局结构。
-
灵活自适应:约束布局支持自动调整布局以适应不同屏幕尺寸和方向的需求。可以根据不同的约束条件,自动调整视图的位置和大小,使布局具有良好的响应性。
-
性能优化:约束布局对渲染性能进行了优化,减少了布局层次结构的复杂性,并提供了扁平的视图层次结构,从而提高了布局的绘制速度。
使用方法
-
添加依赖:在项目的
build.gradle
文件中添加约束布局的依赖项:implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
-
布局文件中使用:在 XML 布局文件中使用
ConstraintLayout
标签作为根布局。然后通过设置视图之间的约束条件来定义布局结构。<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 在这里定义视图和约束条件 --> </androidx.constraintlayout.widget.ConstraintLayout>
-
设置约束条件:在
ConstraintLayout
中定义的子视图可以通过以下属性设置约束条件:app:layout_constraintStart_toStartOf
: 设置视图的开始边与另一个视图的开始边对齐。app:layout_constraintEnd_toEndOf
: 设置视图的结束边与另一个视图的结束边对齐。app:layout_constraintTop_toTopOf
: 设置视图的顶部与另一个视图的顶部对齐。app:layout_constraintBottom_toBottomOf
: 设置视图的底部与另一个视图的底部对齐。app:layout_constraintHorizontal_bias
: 设置视图在水平方向上的偏移。app:layout_constraintVertical_bias
: 设置视图在垂直方向上的偏移。app:layout_constraintWidth_percent
: 设置视图的宽度占父布局宽度的百分比。app:layout_constraintHeight_percent
: 设置视图的高度占父布局高度的百分比。
这些属性可以通过拖拽视图或直接在 XML 布局文件中手动设置。
-
约束布局编辑器:Android Studio 提供了可视化的约束布局编辑器,可以通过拖拽视图和设置约束条件来创建约束布局。在布局编辑器中选择 “Design” 视图并点击 “Show Constraints” 按钮,即可打开约束布局编辑器。
总的来说,约束布局是 Android 开发中非常强大和灵活的布局容器,可以帮助开发者轻松定义复杂的布局结构和适应不同屏幕尺寸。通过设置视图之间的约束条件,可以实现丰富多样的用户界面。
当涉及 Android 布局管理时,表格布局(TableLayout)和帧布局(FrameLayout)是两种常用的布局类型,它们各自具有独特的特点和适用场景。
4.表格布局(TableLayout)
特点:
- 表格布局是一种用于显示数据的布局方式,类似 HTML 中的表格。
- 它将视图放置在行(TableRow)和列(TableCell)的交叉点上,使得数据能够以表格的形式呈现。
- 表格布局适合用于显示固定行列的数据,例如日历、排名榜单等。
使用场景:
- 当需要在应用中展示类似于电子表格或者多行多列数据的时候,表格布局是一个不错的选择。
- 适合用于静态数据展示,因为表格布局的行列数通常是静态定义的。
表格布局示例代码:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow>
<TextView
android:text="姓名"
android:padding="10dp"
android:textStyle="bold" />
<TextView
android:text="年龄"
android:padding="10dp"
android:textStyle="bold" />
<TextView
android:text="性别"
android:padding="10dp"
android:textStyle="bold" />
</TableRow>
<TableRow>
<TextView
android:text="张三"
android:padding="10dp" />
<TextView
android:text="25"
android:padding="10dp" />
<TextView
android:text="男"
android:padding="10dp" />
</TableRow>
<TableRow>
<TextView
android:text="李四"
android:padding="10dp" />
<TextView
android:text="30"
android:padding="10dp" />
<TextView
android:text="女"
android:padding="10dp" />
</TableRow>
</TableLayout>
上述代码演示了一个简单的表格布局,用于显示姓名、年龄和性别的数据。
请注意,这些示例只是表格布局和帧布局的基本用法示例,你可以根据自己的需求进行扩展和定制。希望这些示例能帮助你更好地理解表格布局和帧布局的使用方法。
5.帧布局(FrameLayout)
特点:
- 帧布局是一种简单的布局容器,它允许子视图堆叠在一起,每个子视图占据整个空间。
- 子视图的绘制顺序决定了它们的层叠顺序,后添加的子视图会覆盖先添加的子视图。
- 帧布局适合用于只需要显示单个子视图的情况,例如用作容器来切换不同的片段(Fragment)或视图。
使用场景:
- 帧布局常见于需要在同一区域切换显示不同内容的情况,例如页面切换或者视图层叠的情况。
- 适合用于展示单个视图或者作为容器来临时容纳其他布局。
帧布局示例代码:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/image1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textSize="24sp"
android:textColor="#FFFFFF"
android:layout_gravity="center" />
</FrameLayout>
上述代码演示了一个帧布局,其中包含一个 ImageView 和一个 TextView。ImageView 用于显示一张图片,TextView 则显示一个居中的文本。
二,常用前端页面组件
组件名词解释
- 文本框(TextView):用于显示静态文字内容。它是一个不可编辑的文本组件,可以用于显示标题、标签或信息。
- 输入框(EditText):用于接收用户输入的文本内容。它是一个可编辑的文本框,用户可以输入数据,如用户名、密码、搜索内容等。
- 按钮(Button):用于触发某个操作或事件。用户点击按钮后,会执行预定的动作,如提交表单、打开新页面等。
- 滚动条(ScrollView):用于在视图中显示超出屏幕范围的内容,并提供垂直或水平滚动功能。
常用前端页面组件和标签
TextView(文本框)
常用标签:
android:text
:设置显示的文本内容。android:textSize
:设置文本的大小。android:textColor
:设置文本的颜色。android:layout_width
和android:layout_height
:设置视图的宽度和高度。
示例代码:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is a TextView"
android:textSize="18sp"
android:textColor="#000000" />
EditText(输入框)
常用标签:
android:hint
:设置提示信息,当输入框为空时显示。android:inputType
:设置输入类型,比如文本、数字、密码等。android:text
:设置初始文本内容。android:layout_width
和android:layout_height
:设置视图的宽度和高度。
示例代码:
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter your text here"
android:inputType="text" />
Button(按钮)
常用标签:
android:text
:设置按钮上显示的文本。android:onClick
:指定按钮点击时调用的方法。android:layout_width
和android:layout_height
:设置视图的宽度和高度。
示例代码:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit"
android:onClick="handleSubmit"/>
在 Java/Kotlin 中实现 onClick
方法:
public void handleSubmit(View view) {
// Handle button click
}
ScrollView(滚动条)
常用标签:
android:layout_width
和android:layout_height
:设置视图的宽度和高度。android:fillViewport
:设置滚动视图是否扩展到填充视口。
示例代码:
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 放置需要滚动的内容 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Scrollable content 1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Scrollable content 2" />
<!-- 添加更多内容以便滚动 -->
</LinearLayout>
</ScrollView>
综合示例
将这些组件综合起来,可以创建一个包含文本框、输入框、按钮和滚动条的布局。
示例代码:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Username:"
android:textSize="16sp"
android:paddingBottom="8dp" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter your username"
android:inputType="text"
android:paddingBottom="16dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit"
android:onClick="handleSubmit"
android:paddingBottom="16dp" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- 滚动内容开始 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Scrollable content 1"
android:paddingBottom="8dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Scrollable content 2"
android:paddingBottom="8dp" />
<!-- 添加更多内容以便滚动 -->
</LinearLayout>
</ScrollView>
</LinearLayout>
第二章适配器和监听事件
一, 适配器(Adapter)
概念解释
适配器是一种设计模式,它用于在数据源和 UI 组件之间建立连接。适配器可以将数据源(如数组、列表、数据库查询结果等)转换为 UI 组件(如 ListView
、RecyclerView
等)所需要的格式。适配器负责创建视图项,并将数据绑定到这些视图项上。适配器主要用于处理 ListView
和 RecyclerView
等需要展示大量数据的组件。
常见的适配器类型:
在 Android 开发中,适配器(Adapter)是一种用于绑定数据和视图的重要组件。不同类型的适配器用于不同的数据源和视图组件。下面我将解释 ArrayAdapter
、SimpleAdapter
、CursorAdapter
和 RecyclerView.Adapter
这四种适配器的作用和特点:
ArrayAdapter
- 作用:
ArrayAdapter
用于将数组或列表数据与ListView
、Spinner
等视图组件绑定,将数据显示在列表或下拉列表中。 - 特点:简单易用,适用于静态数据源,可以直接传入数组或列表数据进行展示。
SimpleAdapter
- 作用:
SimpleAdapter
用于将键值对数据与ListView
绑定,常用于显示复杂的数据项,例如包含多个文本和图片的列表项。 - 特点:支持多个数据字段,可以自定义每个列表项的布局,适用于展示结构化数据。
CursorAdapter
- 作用:
CursorAdapter
用于将数据库查询结果中的游标数据与ListView
等视图组件绑定,用于显示数据库查询结果。 - 特点:与数据库交互方便,支持实时更新,当底层数据源发生变化时,会自动更新视图。
RecyclerView.Adapter
- 作用:
RecyclerView.Adapter
是用于将数据与RecyclerView
绑定的基类适配器,用于管理RecyclerView
中的数据项和视图项。 - 特点:强大灵活,支持多种布局管理器和动画效果,提供更好的性能和可扩展性,推荐用于大规模数据集的展示。
示例代码
使用 ArrayAdapter
为 ListView
提供数据:
布局文件(res/layout/activity_main.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
活动类(MainActivity.java)
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = findViewById(R.id.listView);
// 数据源
String[] items = {"Apple", "Banana", "Cherry", "Date", "Elderberry"};
// 创建 ArrayAdapter 并绑定数据源
ArrayAdapter<String> adapter = new ArrayAdapter<>(
this,
android.R.layout.simple_list_item_1,
items
);
// 将适配器设置给 ListView
listView.setAdapter(adapter);
}
}
使用 RecyclerView.Adapter
为 RecyclerView
提供数据:
布局文件(res/layout/activity_main.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
项目适配器类(MyAdapter.java)
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<String> mData;
public MyAdapter(List<String> data) {
this.mData = data;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(android.R.layout.simple_list_item_1, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.textView.setText(mData.get(position));
}
@Override
public int getItemCount() {
return mData.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView textView;
ViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(android.R.id.text1);
}
}
}
活动类(MainActivity.java)
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.Arrays;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.recyclerView);
// 数据源
String[] items = {"Apple", "Banana", "Cherry", "Date", "Elderberry"};
MyAdapter adapter = new MyAdapter(Arrays.asList(items));
// 设置 RecyclerView 的布局管理器和适配器
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
}
}
二. 监听事件(Event Listener)
概念解析
监听事件(Event Listener)是用于捕获和处理用户交互(如点击、长按、滑动等)的一种机制。在 Android 中,几乎所有的 UI 组件都支持事件监听器,通过这些监听器可以响应用户的操作。
常见用法
事件监听器通常通过设置特定的回调接口来实现。例如,按钮的点击事件监听器是 OnClickListener
。
相关组件和标签
Button
View.OnClickListener
View.OnLongClickListener
View.OnTouchListener
示例代码
设置按钮的点击事件监听器:
布局文件(res/layout/activity_main.xml)
<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/myButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me" />
</LinearLayout>
活动类(MainActivity.java)
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button myButton = findViewById(R.id.myButton);
// 设置点击事件监听器
myButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 响应点击事件
Toast.makeText(MainActivity.this, "Button Clicked!", Toast.LENGTH_SHORT).show();
}
});
}
}
设置长按事件监听器:
活动类(MainActivity.java)
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button myButton = findViewById(R.id.myButton);
// 设置长按事件监听器
myButton.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// 响应长按事件
Toast.makeText(MainActivity.this, "Button Long Clicked!", Toast.LENGTH_SHORT).show();
return true; // 返回 true 表示事件已处理,不再传递
}
});
}
}
第三章Activity(生命周期)
Activity概念简述
Activity 是 Android 应用程序的基本构建块之一,每个 Activity 具有自己独立的生命周期管理。理解 Activity 的生命周期对于开发稳定且响应迅速的应用程序至关重要。Activity 的生命周期方法让开发者能够在不同状态下执行特定的操作,如初始化资源、保存数据、释放资源等。
Lifecycle 方法
Activity 的生命周期由一系列回调方法来管理,主要包括以下几种:
- onCreate()
- onStart()
- onResume()
- onPause()
- onStop()
- onRestart()
- onDestroy()
生命周期方法详解
-
onCreate(Bundle savedInstanceState)
- 在 Activity 被创建时调用,是生命周期的起点。
- 用于初始化 Activity,例如设置布局、初始化组件等。
- 只会被调用一次,即使 Activity 被重新激活也不会再次调用。
-
onStart()
- 在 Activity 即将变得可见时调用。
- 从 onCreate() 之后调用,或者从 onStop() 之后重新调用。
-
onResume()
- 在 Activity 开始与用户交互之前调用。
- 在 onStart() 之后调用,Activity 已经可见并处于前台。
-
onPause()
- 在系统准备去启动或恢复另一个 Activity 时调用。
- 用于保存未保存的更改、停止动画等。Activity 仍然部分可见,但不再是焦点。
-
onStop()
- 在 Activity 不再可见时调用。
- 用于释放资源、保存数据等。可能会在系统内存不足时被销毁。
-
onRestart()
- 在 Activity 从停止状态重新启动时调用。
- 在 onStop() 之后,再次启动 Activity 时调用。
-
onDestroy()
- 在 Activity 被销毁之前调用。
- 用于释放所有资源,确保没有内存泄漏等。在 finish() 调用或系统决定销毁 Activity 时调用。
Activity生命周期中常见用法
- 初始化和恢复状态: 在
onCreate()
中初始化 UI 组件和数据,在onSaveInstanceState()
和onRestoreInstanceState()
中保存和恢复 UI 状态。 - 资源管理: 在
onResume()
中获取资源(如相机、传感器),在onPause()
中释放。 - 数据持久化: 在
onStop()
中保存数据到数据库或文件,在onStart()
中恢复数据。 - 清理工作: 在
onDestroy()
中释放所有未释放的资源和停止后台任务。
示例代码
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置当前 Activity 使用的布局文件
setContentView(R.layout.activity_main);
// 在此处进行初始化操作,例如设置按钮点击事件
Button myButton = findViewById(R.id.my_button);
myButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 启动另一个 Activity
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
}
});
// 如果存在保存的实例状态,则恢复状态
if (savedInstanceState != null) {
String savedData = savedInstanceState.getString("key");
// 恢复之前的状态
}
}
@Override
protected void onStart() {
super.onStart();
// Activity 即将变得可见
// 在此处可以启动任何需要在界面可见时运行的逻辑
Log.d("MainActivity", "Activity is starting");
}
@Override
protected void onResume() {
super.onResume();
// Activity 已经变得可见并在前台
// 恢复 UI 更新和动画等
Log.d("MainActivity", "Activity is resuming");
}
@Override
protected void onPause() {
super.onPause();
// Activity 即将被停止或覆盖
// 暂停动画、保存未保存的数据等
Log.d("MainActivity", "Activity is pausing");
}
@Override
protected void onStop() {
super.onStop();
// Activity 即将完全不可见
// 释放占用的资源
Log.d("MainActivity", "Activity is stopping");
}
@Override
protected void onRestart() {
super.onRestart();
// Activity 即将从停止状态重新启动
Log.d("MainActivity", "Activity is restarting");
}
@Override
protected void onDestroy() {
super.onDestroy();
// Activity 即将被销毁
// 进行清理工作
Log.d("MainActivity", "Activity is being destroyed");
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// 保存当前 Activity 的状态
outState.putString("key", "some_value");
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// 恢复之前保存的状态
if (savedInstanceState != null) {
String savedData = savedInstanceState.getString("key");
// 使用恢复的数据
}
}
}
代码解析
- onCreate(Bundle savedInstanceState): 初始化 Activity 的界面和数据。如果存在保存的实例状态,则恢复状态。
- onStart(): 在 Activity 即将变得可见时执行,适合运行界面相关逻辑。
- onResume(): 在 Activity 可见并在前台时执行,适合恢复 UI 更新和动画等。
- onPause(): 在 Activity 即将停止或被覆盖时执行,适合暂停动画和保存数据。
- onStop(): 在 Activity 完全不可见时执行,适合释放资源。
- onRestart(): 在 Activity 从停止状态重启时执行。
- onDestroy(): 在 Activity 被销毁前执行,适合进行清理工作。
- onSaveInstanceState(Bundle outState): 保存当前 Activity 的状态。
- onRestoreInstanceState(Bundle savedInstanceState): 恢复之前保存的状态。
第四章Intent组件
Intent 概念简述
Intent
是 Android 中的核心组件之一,用于在应用程序组件之间传递数据。它可以用来描述你想要执行的操作,比如启动一个新的 Activity、启动一个服务或传递广播消息。
Intent 的类型
- 显式 Intent (Explicit Intent): 明确指定目标组件的名称。
- 隐式 Intent (Implicit Intent): 不指定目标组件,通过 Action、Category 和 Data 来匹配合适的组件。
常见用法
- 启动 Activity
- 启动服务
- 发送广播
代码样例
显式 Intent 启动 Activity
显式 Intent 是通过明确指定目标 Activity 的类名来启动的。
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Button to move to SecondActivity
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 创建显式 Intent
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
// 添加数据
intent.putExtra("key", "Hello, SecondActivity!");
// 启动目标 Activity
startActivity(intent);
}
});
}
}
SecondActivity.java
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
// 获取 Intent 携带的数据
Intent intent = getIntent();
String message = intent.getStringExtra("key");
// 显示数据
TextView textView = findViewById(R.id.textView);
textView.setText(message);
}
}
隐式 Intent 启动 Activity
隐式 Intent 不指定具体类名,而是通过动作(Action)、类别(Category)和数据(Data)来启动合适的组件。
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Button to send an implicit intent
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 创建隐式 Intent
Intent intent = new Intent(Intent.ACTION_VIEW);
// 设置数据 URI
intent.setData(Uri.parse("http://www.example.com"));
// 启动系统可以处理的 Activity
startActivity(intent);
}
});
}
}
启动 Service
启动服务也是通过 Intent 实现的,但通常需要将 Intent 传递给 startService()
方法。
MyService.java
public class MyService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 服务逻辑
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 启动服务
Intent intent = new Intent(this, MyService.class);
startService(intent);
}
}
发送广播
通过 Intent 发送广播消息,其他组件可以注册 BroadcastReceiver
来接收这些消息。
BroadcastSender.java
public class BroadcastSender {
public static void sendBroadcast(Context context) {
Intent intent = new Intent("com.example.CUSTOM_INTENT");
intent.putExtra("message", "Hello, BroadcastReceiver!");
context.sendBroadcast(intent);
}
}
MyBroadcastReceiver.java
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if ("com.example.CUSTOM_INTENT".equals(intent.getAction())) {
String message = intent.getStringExtra("message");
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
}
}
AndroidManifest.xml
<application>
...
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="com.example.CUSTOM_INTENT"/>
</intent-filter>
</receiver>
</application>
第五章Fragment组件
Fragment 组件概念简述
Fragment 是 Android 应用中的一种 UI 组件,可以在 Activity 中嵌入多个 Fragment,并且可以在不同的设备屏幕上灵活地调整布局。Fragment 有自己的生命周期,可以处理自己的输入事件,还可以在多个 Activity 之间共享。
常见用法
- 在 Activity 中嵌入 Fragment: 通过在 XML 布局文件中定义
<fragment>
标签或者在代码中动态添加 Fragment 来嵌入到 Activity 中。 - Fragment 间的通信: 不同的 Fragment 可以通过宿主 Activity 进行通信,也可以通过 ViewModel 或接口进行通信。
- 适配不同设备屏幕: 可以根据设备的屏幕大小和方向来管理和调整 Fragment 的布局。
相关组件
- FragmentActivity: 用于支持 Fragment 的 Activity 类。
- FragmentManager: 用于在 Activity 运行时管理 Fragment 的类。
- FragmentTransaction: 用于在 Activity 运行时执行 Fragment 添加、替换、删除等操作的类。
相关标签
- : 在 XML 布局文件中定义 Fragment。
- : 用于在代码中动态添加 Fragment 的容器布局。
代码样例
在 XML 布局文件中定义 Fragment
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 容纳 Fragment 的 FrameLayout -->
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
MyFragment.java
public class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// 加载 Fragment 的布局文件
return inflater.inflate(R.layout.fragment_layout, container, false);
}
}
MainActivity.java
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 在 activity_main.xml 中的 FrameLayout 中动态添加 Fragment
if (savedInstanceState == null) {
MyFragment fragment = new MyFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
}
}
通过代码动态添加或替换 Fragment
MainActivity.java
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 动态替换 Fragment
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AnotherFragment fragment = new AnotherFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, fragment)
.addToBackStack(null) // 将事务添加到返回栈,以便用户按下返回键时能够回退
.commit();
}
});
}
}
第六章数据存储和访问
数据存储和访问功能
在 Android 开发中,数据存储与访问功能是非常重要的,它允许应用程序保存和读取用户数据、应用程序配置和其他持久化数据。Android 提供了多种方式来实现数据的存储和访问,包括数据库、文件存储、SharedPreferences 和 ContentProvider 等。
常见用法
- 数据库存储: 使用 SQLite 数据库进行结构化数据的存储和访问,可以使用 SQLiteOpenHelper 类来创建和管理数据库。
- 文件存储: 将数据以文件的形式存储在设备的内部存储空间或外部存储空间中,可以使用 File 类和相关的输入输出流进行读写操作。
- SharedPreferences: 使用 SharedPreferences 存储和访问简单的键值对数据,适合保存应用程序的配置信息和用户偏好设置。
- ContentProvider: 通过 ContentProvider 实现跨应用程序之间共享数据,并提供标准的接口来访问和操作数据。
相关组件
- SQLiteOpenHelper: 用于创建和管理 SQLite 数据库的类。
- SQLiteDatabase: 用于执行 SQL 操作的类。
- File: 用于表示文件的类,提供文件的读写操作方法。
- SharedPreferences: 用于存储和访问简单键值对数据的类。
- ContentProvider: 用于跨应用程序之间共享数据的类,提供了标准的接口来访问和操作数据。
代码样例
数据库存储 - 使用 SQLiteOpenHelper
MyDatabaseHelper.java
public class MyDatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "my_database.db";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NAME = "my_table";
private static final String COLUMN_ID = "_id";
private static final String COLUMN_NAME = "name";
public MyDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String createTableQuery = "CREATE TABLE " + TABLE_NAME + " (" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
COLUMN_NAME + " TEXT)";
db.execSQL(createTableQuery);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// 升级数据库时的操作
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private MyDatabaseHelper databaseHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
databaseHelper = new MyDatabaseHelper(this);
SQLiteDatabase db = databaseHelper.getWritableDatabase();
// 执行数据库操作
// ...
}
}
文件存储
// 写入文件
try {
FileOutputStream fos = openFileOutput("file.txt", Context.MODE_PRIVATE);
String content = "Hello, World!";
fos.write(content.getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
// 读取文件
try {
FileInputStream fis = openFileInput("file.txt");
byte[] buffer = new byte[1024];
int bytesRead = fis.read(buffer);
String content = new String(buffer, 0, bytesRead);
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
SharedPreferences
// 存储数据
SharedPreferences sharedPreferences = getSharedPreferences("my_pref", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("name", "John");
editor.putInt("age", 25);
editor.apply();
// 读取数据
SharedPreferences sharedPreferences = getSharedPreferences("my_pref", Context.MODE_PRIVATE);
String name = sharedPreferences.getString("name", "");
int age = sharedPreferences.getInt("age", 0);
ContentProvider
ContentProvider 的使用涉及到更多的代码和配置,这里提供一个简单的示例以供参考。
MyContentProvider.java
public class MyContentProvider extends ContentProvider {
private static final String AUTHORITY = "com.example.myapp.provider";
private static final String BASE_PATH = "items";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);
private MyDatabaseHelper databaseHelper;
@Override
public boolean onCreate() {
databaseHelper = new MyDatabaseHelper(getContext());
return true;
}
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = databaseHelper.getReadableDatabase();
Cursor cursor = db.query(MyDatabaseHelper.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
// 其他 CRUD 操作的实现
// ...
}
第七章Android http请求和基于TCP的Socket通信
Android http请求
在 Android 开发网络模块中提供了 HTTP 请求和基于 TCP 的 Socket 通信的功能,允许应用程序与远程服务器进行数据交换和通信。这两种方式分别适用于不同的场景和需求。
解释说明
HTTP 请求是一种基于客户端-服务器架构的协议,用于传输和交换超文本信息。在 Android 开发中,可以使用 HttpURLConnection 或者第三方库(如 OkHttp)来发送 HTTP 请求,并处理来自服务器的响应数据。
常见用法
-
发送 GET 请求:
URL url = new URL("http://www.example.com/api/data"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); try { InputStream in = new BufferedInputStream(urlConnection.getInputStream()); // 读取并处理服务器返回的数据 } finally { urlConnection.disconnect(); }
这段代码首先创建了一个 URL 对象表示目标服务器的地址,然后打开一个 HTTP 连接,并从连接的输入流中读取服务器返回的数据。
-
发送 POST 请求:
URL url = new URL("http://www.example.com/api/post"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); try { urlConnection.setRequestMethod("POST"); urlConnection.setDoOutput(true); OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream()); // 写入请求体数据 out.write("data=example".getBytes()); out.flush(); out.close(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); // 读取并处理服务器返回的数据 } finally { urlConnection.disconnect(); }
这段代码向目标服务器发送了一个 POST 请求,并在请求体中包含了数据,然后从连接的输入流中读取服务器返回的数据。
相关组件
- HttpURLConnection: 用于发送 HTTP 请求和接收服务器响应的类。
- URL: 用于表示统一资源定位符的类,用于构建目标服务器的地址。
- InputStream/OutputStream: 用于读取和写入数据的输入输出流类。
基于 TCP 的 Socket 通信
解释说明
基于 TCP 的 Socket 通信是一种底层的网络通信方式,它允许应用程序在客户端和服务器之间建立持久的连接,并进行双向数据传输。
常见用法
-
创建 Socket 客户端:
Socket socket = new Socket("server_ip", server_port); OutputStream out = socket.getOutputStream(); // 向服务器发送数据 out.write("Hello, Server!".getBytes()); out.flush(); InputStream in = socket.getInputStream(); // 从服务器接收数据 // ... socket.close();
这段代码创建了一个 Socket 对象并连接到指定的服务器,然后通过输出流向服务器发送数据,并通过输入流接收服务器返回的数据。
-
创建 Socket 服务器:
ServerSocket serverSocket = new ServerSocket(server_port); Socket clientSocket = serverSocket.accept(); InputStream in = clientSocket.getInputStream(); // 从客户端接收数据 // ... OutputStream out = clientSocket.getOutputStream(); // 向客户端发送数据 out.write("Hello, Client!".getBytes()); out.flush(); clientSocket.close();
这段代码创建了一个 ServerSocket 对象并监听指定端口,当有客户端连接时,接受连接并获取输入输出流进行数据交换。
相关组件
- Socket: 用于表示 TCP 连接的套接字类,用于建立客户端和服务器之间的连接。
- ServerSocket: 用于创建 TCP 服务器的类,用于接受客户端的连接请求。