Fragment(二)

来源:互联网 发布:淘宝密码忘了无法显示 编辑:程序博客网 时间:2024/05/17 01:46

碎片的生命周期


碎片的状态

1.运行状态

当一个碎片是可见的,并且它所关联的活动正处于运行状态时,该碎片也处于运行状态。

2.暂停状态

当一个活动进入暂停状态时(由于另一个未占满屏幕的活动被添加到了栈顶),与它相关联的可见碎片就会进入到暂停状态。

3.停止状态

当一个活动进入停止状态时,与它相关联的碎片就会进入到停止状态。或者通过调用FragmentTransaction的remove()、replace()方法将碎片从活动中移除,但有在事务提交之前调用addToBackStack()方法,这时的碎片也会进入到停止状态。总的来说,进入停止状态的碎片对于用户来说是完全不可见的,有可能被系统回收。

4.销毁状态

碎片总是依附于活动而存在的,因此当活动被销毁时,与它相关联的碎片就会进入到销毁状态。或者通过调用FragmentTransaction的remove()、replace()方法将碎片从活动中移除,但在事务提交之前并没有调用addToBackStack()方法,这时的碎片也会进入到销毁状态。


碎片的回调方法

1.onAttach()

当碎片和活动建立关联的时候调用

2.onCreateView()

为碎片创建视图(加载布局)时调用

3.onActivityCreated()

确保与碎片相关联的活动一定已经创建完毕的时候调用

4.onDestroyView()

当与碎片关联的视图被移除的时候调用

5.onDetach()

当碎片和活动解除关联的时候调用





public class RightFragment extends Fragment {public static final String TAG = "RightFragment";@Overridepublic void onAttach(Activity activity) {super.onAttach(activity);Log.d(TAG, "onAttach");}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.d(TAG, "onCreate");}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {Log.d(TAG, "onCreateView");View view = inflater.inflate(R.layout.right_fragment, container, false);return view;}@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);Log.d(TAG, "onActivityCreated");}@Overridepublic void onStart() {super.onStart();Log.d(TAG, "onStart");}@Overridepublic void onResume() {super.onResume();Log.d(TAG, "onResume");}@Overridepublic void onPause() {super.onPause();Log.d(TAG, "onPause");}@Overridepublic void onStop() {super.onStop();Log.d(TAG, "onStop");}@Overridepublic void onDestroyView() {super.onDestroyView();Log.d(TAG, "onDestroyView");}@Overridepublic void onDestroy() {super.onDestroy();Log.d(TAG, "onDestroy");}@Overridepublic void onDetach() {super.onDetach();Log.d(TAG, "onDetach");}}


当RightFragment第一次被加载到屏幕上时


点击LeftFragment中的按钮


由于AnotherRightFragment替换了RightFragment,此时的RightFragment进入了停止状态,因此onPause()、onStop()和onDestroyView()方法会得到执行

当然如果在替换的时候没有调用addToBackStack()方法,此时的RightFragment就会进入销毁状态,onDestroy()和onDetach()方法就会得到执行


接着按下Back键,RightFragment会重新回到屏幕



由于RightFragment重新回到了运行状态,因此onActivityCreated()、onStart()和onResume()方法会得到执行

注意此时onCreate()和onCreateView()方法并不会执行,因为我们借助了addToBackStack()方法使得RightFragment和它的视图并没有销毁


再次按下Back键退出程序


依次会执行onPause()、onStop()、onDestroyView()、onDestroy()和onDetach()方法



动态加载布局的技巧


如何使程序能够通过设备的分辨率或屏幕大小在运行时来决定加载哪个布局?

使用限定符(Qualifiers)

修改activity_main.xml文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.fragmenttest.MainActivity" >    <fragment        android:id="@+id/left_fragment"        android:name="com.example.fragmenttest.LeftFragment"        android:layout_width="match_parent"        android:layout_height="match_parent" /></LinearLayout>

只留下一个左侧碎片,并让它充满整个父布局


接着在res目录下新建layout-large文件夹,在这个文件夹下新建一个布局,也叫做activity_main.xml


<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <fragment        android:id="@+id/left_fragment"        android:name="com.example.fragmenttest.LeftFragment"        android:layout_width="0dp"        android:layout_height="match_parent"        android:layout_weight="1" />    <fragment        android:id="@+id/right_fragment"        android:name="com.example.fragmenttest.RightFragment"        android:layout_width="0dp"        android:layout_height="match_parent"        android:layout_weight="1" /></LinearLayout>


layout/activity_main布局只包含了一个碎片,即单页模式

而layout-large/activity_main布局包含了两个碎片,即双页模式

其中large就是一个限定符,那些屏幕被认为是large的设备就会自动加载layout-large文件夹下的布局,而小屏幕的设备则还是会加载layout文件夹下的布局


屏幕特征

限定符

描述

大小

small

提供给小屏幕设备的资源

normal

提供给中等屏幕设备的资源

large

提供给大屏幕设备的资源

xlarge

提供给超大屏幕设备的资源

分辨率

ldpi

提供给低分辨率设备的资源(120dpi以下)

mdpi

提供给中等分辨率设备的资源(120dpi到160dpi)

hdpi

提供给高分辨率设备的资源(160dpi到240dpi)

xhdpi

提供给超高分辨率设备的资源(240dpi到320dpi)

方向

land

提供给横屏设备的资源

port

提供给竖屏设备的资源



使用最小宽度限定符(Smallest-width Qualifier)


在res目录下新建layout-sw600dp文件夹,然后在这个文件夹下新建activity_main.xml布局

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    >        <fragment        android:id="@+id/left_fragment"        android:name="com.example.fragmenttest.LeftFragment"        android:layout_width="0dp"        android:layout_height="match_parent"        android:layout_weight="1"        />        <fragment        android:id="@+id/right_fragment"        android:name="com.example.fragmenttest.RightFragment"        android:layout_width="0dp"        android:layout_height="match_parent"        android:layout_weight="3"        /></LinearLayout>


这就意味着,当程序运行在屏幕宽度大于600dp的设备上时,会加载layout-sw600dp/activity_main布局

当程序运行在屏幕宽度小于600dp的设备上时,则仍然加载默认的layout/activity_main布局


需要注意的是,最小宽度限定符是在Android 3.2版本引入的





0 0
原创粉丝点击