第四章 不可不会的Activity和Fragment【Android基础学习】
前言
以下内容源自《【Android】》
仅供学习交流使用
版权
禁止其他平台发布时删除以下此话
本文首次发布于CSDN平台
作者是CSDN@日星月云
博客主页是https://jsss-1.blog.csdn.net
禁止其他平台发布时删除以上此话
推荐
【天哥】Android开发视频教程最新版 Android Studio开发
图片资源来自:
https://github.com/jinjungle/skypan-yes-code
开源
日星月云 / 安卓基础学习:https://gitee.com/jsss-1/android-basic-learning
jsss-1 / android-basic-learning:https://github.com/jsss-1/android-basic-learning
第四章 不可不会的Activity和Fragment
这章的界面LifeCycle、Jump、Fragment在UI界面的GridView和RecyclerView中间
4-1-1 Activity创建三部曲
- 新建类继承Activity或其子类
- 在AndroidManifest中声明
- 创建layout并在Activity的onCreate中设置
TestActivity
activity_test.xml
AndroidManifest.xml设置Activity属性
- android:theme=“test” 标签
- android:theme="@style/Theme.AppCompat.Light.NoActionBar"无,可以application中设置
- android:screenOrientation=“portrait” 竖屏显示
- android:launchMode=""启动模式
- intent-filter设置启动Activity
<activity
android:name=".MainActivity"
android:exported="true"
android:theme="test"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
android:screenOrientation="portrait"
android:launchMode="">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
4-1-2 Activity的生命周期
LifeCycleActivity
启动
----onCreate----
----onStart----
----onResume----
退出
----onPause----
----onStop----
----onDestroy----
退到后台
----onPause----
----onStop----
切回前台
----onRestart----
----onStart----
----onResume----
最常用
启动:onCreate
切到后台:onPause
切回前台:onResume
退出:onDestroy
4-1-3 Activity的跳转和数据传递
- 显式跳转和隐式跳转
- Activity之间的数据传递
- startActivityForResult:启动Activity,结束后返回结果
AActivity
BActivity
activity_a.xml
activity_b.xml
4-1-4 Activity的4种启动模式
Activity的android:launchMode属性
- standard:标准模式,默认
- singleTop:Task栈顶复用模式
- singleTask:Task栈内复用模式
- singleInstance:全局单例模式
standard
Activity是由任务栈管理的,每启动一个Activity,就会被放入栈中,按返回键,就会从栈顶移除一个Activity。
standard是默认的启动模式,即标准模式。每启动一个Activity,都会创建一个新的实例。
taskid:任务栈
hash:实例
默认的栈名称:包名
可以通过android:taskAffinity=".asdfghjkdfghj"
,设置栈名称,必须前面有个.
设置android:launchMode为standard
<activity
android:name=".jump.AActivity"
android:label="A"
android:launchMode="standard"
android:exported="false" />
<activity
android:name=".jump.BActivity"
android:label="B"
android:launchMode="standard"
android:exported="true">
<intent-filter>
<action android:name="com.example.test.BActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
测试:在A中点击跳转到A
现象:创建了不同的实例
//进入A
2024-06-08 19:08:08.644 10434-10434 AActivity com.example.helloworld D ----onCreate----
2024-06-08 19:08:08.646 10434-10434 AActivity com.example.helloworld D taskid:225 ,hash:205697094
2024-06-08 19:08:08.648 10434-10434 AActivity com.example.helloworld D com.example.helloworld
//跳转到A
2024-06-08 19:10:43.285 10434-10434 AActivity com.example.helloworld D ----onCreate----
2024-06-08 19:10:43.293 10434-10434 AActivity com.example.helloworld D taskid:225 ,hash:265426351
2024-06-08 19:10:43.296 10434-10434 AActivity com.example.helloworld D com.example.helloworld
测试:在A中点击jump跳转到B
现象:创建了不同的实例
(视频中B是onNewIntent,是因为他的BActivity.onCreate()信息写错了,应该是onCreate)
//进入A
2024-06-08 19:18:16.649 2148-2148 AActivity com.example.helloworld D ----onCreate----
2024-06-08 19:18:16.649 2148-2148 AActivity com.example.helloworld D taskid:228 ,hash:165672095
2024-06-08 19:18:16.651 2148-2148 AActivity com.example.helloworld D com.example.helloworld
//跳转到B
2024-06-08 19:18:35.546 2148-2148 BActivity com.example.helloworld D ----onCreate----
2024-06-08 19:18:35.554 2148-2148 BActivity com.example.helloworld D taskid:228 ,hash:125393259
2024-06-08 19:18:35.586 2148-2148 BActivity com.example.helloworld D com.example.helloworld
singleTop
当要启动的目标Activity已经位于栈顶时,不会创建新的实例,会复栈用顶的Activity,并且其onNewntent()方法会被调用;
如果目标Activity不在栈顶,则跟standard一样创建新的实例。
设置android:launchMode为singleTop
<activity
android:name=".jump.AActivity"
android:label="A"
android:launchMode="singleTop"
android:exported="false" />
<activity
android:name=".jump.BActivity"
android:label="B"
android:launchMode="singleTop"
android:exported="true">
<intent-filter>
<action android:name="com.example.test.BActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
测试:在A中点击跳转到A,再跳转到B
现象:跳转到A,hash码一致,在栈顶,所以复用实例
//进入A
2024-06-08 19:30:57.559 5429-5429 AActivity com.example.helloworld D ----onCreate----
2024-06-08 19:30:57.560 5429-5429 AActivity com.example.helloworld D taskid:230 ,hash:106511291
2024-06-08 19:30:57.562 5429-5429 AActivity com.example.helloworld D com.example.helloworld
//跳转到A
2024-06-08 19:31:18.483 5429-5429 AActivity com.example.helloworld D ----onNewIntent----
2024-06-08 19:31:18.488 5429-5429 AActivity com.example.helloworld D taskid:230 ,hash:106511291
2024-06-08 19:31:18.490 5429-5429 AActivity com.example.helloworld D com.example.helloworld
//跳转到B
2024-06-08 19:33:15.637 5429-5429 BActivity com.example.helloworld D ----onCreate----
2024-06-08 19:33:15.638 5429-5429 BActivity com.example.helloworld D taskid:230 ,hash:147131998
2024-06-08 19:33:15.641 5429-5429 BActivity com.example.helloworld D com.example.helloworld
singleTask
在同一个任务栈中,如果要启动的目标Activity已经在栈中,则会复用该Activity,并调用其onNewIntent()方法,并且该Activity上面的Activity会被清除;如果栈中没有,则创建新的实例。
没有演示
singleInstance
全局复用,不管哪个Task栈,只要存在目标Activity,就复用。每个Activity占有一个新的Task栈。
不经常使用
2024-6-8 19:55:05
4-2-1 Fragment详解(一)
2024-6-9 22:18:01
- Fragment有自己的生命周期
- Fragment依赖于Activity
- Fragment通过getActivity()可以获取所在的Activity;Activity通过FragmentManager的findFragmentById()或findFragmentByTag()获取Fragment
- Fragment和Activity是多对多的关系
AFragment
BFragment
ContainerActivity
activity_container.xml
fragment_a.xml
fragment_b.xml
4-2-2 Fragment详解(二)
- Fragment中getActivity()为null的问题
- 向Fragment传递参数
public static AFragment newInstance(String title) {
AFragment fragment = new AFragment();
Bundle bundle = new Bundle();
bundle.putString("title", title);
fragment.setArguments(bundle);
return fragment;
}
aFragment = AFragment.newInstance("我是参数");
getArguments().getString("title")
4-2-3 Fragment详解(三)
- Fragment回退栈
getParentFragmentManager().beginTransaction().replace(R.id.fl_container, bFragment).commitAllowingStateLoss();
开始测试
进入AFragment中
点击跳转BFragment
点击返回
直接到了UI界面了
addToBackStack
放到回退栈中
getParentFragmentManager().beginTransaction().replace(R.id.fl_container, bFragment).addToBackStack(null).commitAllowingStateLoss();
测试一
进入AFragment中,打印---onCreateView----
点击跳转BFragment
点击返回
返回到AFragment,打印---onCreateView----
再点击返回
直接到了UI界面了
打印---onCreateView----
说明:实例是同一个实例,但是视图会重新创建
测试二
进入AFragment中
点击替换文字,A变为新文字
点击跳转BFragment
点击返回
返回到AFragment,但是文字还原了
但是我们希望是改变之后的状态
replace是remove和add的组合操作
// ContainerActivity:添加tag标签a
// getSupportFragmentManager().beginTransaction().add(R.id.fl_container, aFragment).commitAllowingStateLoss();
getSupportFragmentManager().beginTransaction().add(R.id.fl_container, aFragment,"a").commitAllowingStateLoss();
先隐藏A再把B添加,放到回退栈中
Fragment fragment = getParentFragmentManager().findFragmentByTag("a");
if (fragment != null) {
getParentFragmentManager().beginTransaction().hide(fragment).add(R.id.fl_container, bFragment).addToBackStack(null).commitAllowingStateLoss();
}else {
getParentFragmentManager().beginTransaction().replace(R.id.fl_container, bFragment).addToBackStack(null).commitAllowingStateLoss();
}
进入AFragment中,打印---onCreateView----
点击替换文字,A变为新文字
点击跳转BFragment
点击返回,没有打印---onCreateView----
返回到AFragment,是替换后的状态
就是hide替代replace,因为hide不是清空只是隐藏,从而实现了堆叠效果,所以返回时能回退到非重置状态
4-2-4 Fragment详解(四)
- Fragment和Activity的通信
公共方法
回调接口
公共方法编写步骤
1在ContainerActivity
中写一个公共方法setData
2在AFragment
中直接调用((ContainerActivity) getActivity()).setData("你好");
回调接口编写步骤
1在AFragment
中编写接口IOnMessageClick
,声明方法onClick
2ContainerActivity
实现AFragment.IOnMessageClick
,变重写onClick
3在AFragment
中onAttach
中关联Activity listener = (IOnMessageClick) context;
4AFragment
中调用listener.onClick(“你好”);
2024-6-10 00:05:48
最后
2024-6-10 00:05:48
迎着日光月光星光,直面风霜雨霜雪霜。