这是我参与「第四届青训营 」笔记创作活动的第3天。
2 Fragment
2.1 Fragment是什么
Fragment是一个轻量级页面容器,设计之初是为了解决屏幕碎片化问题,能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用得非常广泛。Fragment是依赖于Activity的,不能独立存在,可以在一个Activity中组合多个Fragment,从而实现多窗格界面,也可以在多个Activity中重复使用某个Fragment,可以将Fragment视为Activity的模块化组成,
这是之前做的一个Fragment练习的界面截图,在整个界面截图中有两个Fragment,左边的是标题栏Fragment,右边是内容Fragment,这两个Fragment嵌入在一个Activity中。
2.2 Fragment基本用法
2.2.1 创建Fragment
-
创建一个Fragment的子类
-
在这个子类中重写onCreateView()方法,在该方法中通过调用LayouInflater对象中的inflate()方法加载布局
代码如下所示:
@Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.news_content_frag,container,false); return view; }
2.2.2 将Fragment添加到Activity中
-
静态添加
使用标签在Activity布局文件中添加Fragment,示例代码如下:
<!-- 上一层布局为LinearLayout--> <fragment android:id="@+id/left_fragment" android:name="cn.edu.jssvc.wangyu.myframenttest.LeftFragment" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" /> -
动态添加
第一步:在Activity布局文件中,可以声明一个FrameLayout作为Fragment的容器,代码如下:
<FrameLayout android:id="@+id/right_layout" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="#03A9F4">第二步:将Fragment添加到创建的容器内
//创建待添加的Fragment实例 RightFragment rightFragment = new RightFragment(); //获取FragmentManager FragmentManager fragmentManager = getSupportFragmentManager(); //开启一个事务 FragmentTransaction transaction = fragmentManager.beginTransaction(); //向容器内添加或替换Fragment transaction.replace(R.id.right_layout,rightFragment); //提交事务 transaction.commit();
2.2.3 Fragment与Activity交互
-
组件获取
- Fragment获取Activity中的组件:getActivity().findViewById(R.id.xxx)
- Activity获取Fragment中的组件:getFragmentManager.findFragmentById(R.id.fragment_xxx)
-
数据传递
- Activity传递数据给Fragment:setArguments(Bundle bundle)
- Fragment传递数据给Activity
- 通过对象直接传递(方法调用/接口调用)
- 通过Viewmodel / handler / broadcast / eventbus等通信
2.3 Fragment的生命周期
2.3.1 Fragment的4种生命周期状态
-
Active 运行状态
-
Pause 暂停状态
-
Stop 停止状态
-
Killed 消亡状态
2.3.2 Fragment生命周期的回调方法
- onAttach():当Fragment和Activity建立关联时调用
- onCreateView():为Fragment创建视图(加载布局)时调用
- onActivityCreated():确保与Fragment相关联的Activity已经创建完毕是时调用
- onDestoryView():当与Fragment关联的视图被移除时调用
- onDetach():当Fragment和Activity解除关联时调用
2.3.3 Fragment生命周期小结
- 启动:onAtttach()→onCreate()→onCreateView()→onActivityCreated()→onStart()→onResume()→Resumed
- 退出:Resumed→onPause()→onStop()→onDestoryView()→onDestory()→onDetach()
- 部分遮挡:Resumed→onPause()→Paused
- 部分遮挡恢复:Paused→onResume()→Resumed
- 完全遮挡:Resumed→onPause()→onStop()→onDestoryView()
- 完全遮挡恢复:onCreateView()→onActivityCreated()→onStart()→onResumed()→Resumed
注:Fragment生命周期可通过FragmentTransaction.setMaxLifecycle()手动干预
3 Service
3.1 Service是什么
serice是Android中实现程序后台运行的解决方案,它非常适合执行那些不需要和用户交互而且还需要长期运行的任务。Service的运行不依赖于任何用户界面,即使程序被切换到后台,或者用户打开了另外一个应用应用程序,Service依然能够保持正常运行。
3.2 Service基本用法
3.2.1 定义一个Service
在AndroidStudio中,右击包名→New→Service→Service,最后会弹出一个如下窗口:
ps:Exported属性表示是否将这个Service暴露给外部其他程序访问,Enabled属性表示是否启动这个Service
3.2.2 声明Service
在AndroidMainfest.xml中使用标签可进行Service的声明,用上述方法定义Service会自动声明,示例如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<application
...>
<service
android:name=".MyService3"
android:enabled="true"
android:exported="true" />
...
</activity>
</application>
</manifest>
3.2.3 启动、停止、绑定和解绑Service
-
启动服务
// 创建显式Intent,指定要启动的Service类 Intent startIntent = new Intent(this, MyService.class); startService(startIntent); // 启动服务 -
停止服务
Intent stopIntent = new Intent(this, MyService.class); stopService(stopIntent); // 停止服务 -
绑定
Intent bindIntent = new Intent(this, MyService.class); bindService(bindIntent, connection, BIND_AUTO_CREATE); // 绑定服务connection是ServiceConnection的实例
-
解绑
unbindService(connection); // 解绑服务
3.2.4 Service与Activity通信
-
定义Binder子类,并实现getService()方法,返回Service对象
class DownloadBinder extends Binder { public void startDownload() { Log.d("MyService", "startDownload executed"); } public int getProgress() { Log.d("MyService", "getProgress executed"); return 0; } } -
实现Service类onBind()方法,返回上述Binder对象
private DownloadBinder mBinder = new DownloadBinder(); ... @Override public IBinder onBind(Intent intent) { Log.d("MyService", "onBind executed"); return mBinder; } -
实例化ServiceConnection对象,实现onServiceConnected()方法
private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { downloadBinder = (MyService.DownloadBinder) service; downloadBinder.startDownload(); downloadBinder.getProgress(); } }; -
Activity中调用bindService(),并传递步骤3的ServiceConnection对象
Intent bindIntent = new Intent(this, MyService.class); bindService(bindIntent, connection, BIND_AUTO_CREATE); // 绑定服务 -
Activity可以通过调用Service实例中的方法进行直接通信
3.2.5 Service生命周期内的一些回调方法
- onCreate():服务正在创建中
- onStartCommand():调用了startService,服务正在启动
- onBind():客户端绑定到具有bindService()的服务
- onUnbind():所有客户端都使用unbindService()取消绑定
- onRebind():客户端绑定到具有bindService()的服务,onUnbind()已经被调用
- onDestory:该服务不再使用并被销毁