zoukankan      html  css  js  c++  java
  • Fragment (一)

    1,简介

    Fragement(碎片)允许将Activity拆分成多个完全独立封装的可重用组件,每个组件有它自己的生命周期和UI布局,由此可见,Fragement依赖于Activity,它的生命周期直接被其所属的宿主activity的生命周期影响。

    形象的理解Fragement,手机屏幕如下图所示:

    image

    Fragement 具有以下优点:

    • 组件重用,多个Activity可重用同一个Fragement;
    • 为不同屏幕大小的设备创建动态的灵活的UI,在Activity运行过程中,可以添加、移除或者替换Fragment(add()、remove()、replace())

    2,生命周期

    Fragement的生命周期镜像它的宿主Activity的生命周期事件。若Activity进入active-resumed状态的时候,添加或者移除一个Fragement就会影响它自己的生命周期。

    Fragement生命周期方面如下:

    /**
     * Listing 4-4: Fragment skeleton code
     * Listing 4-5: Fragment lifecycle event handlers
     */
    package com.paad.fragments;
    
    import android.app.Activity;
    import android.app.Fragment;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    
    public class MySkeletonFragment extends Fragment {
    
      // Called when the Fragment is attached to its parent Activity.
      @Override
      public void onAttach(Activity activity) {
        super.onAttach(activity);
        // Get a reference to the parent Activity.
      }
    
      // Called to do the initial creation of the Fragment.
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Initialize the Fragment.
      }
    
      // Called once the Fragment has been created in order for it to
      // create its user interface.
      @Override
      public View onCreateView(LayoutInflater inflater, 
                               ViewGroup container,
                               Bundle savedInstanceState) {
        // Create, or inflate the Fragment's UI, and return it. 
        // If this Fragment has no UI then return null.
        return inflater.inflate(R.layout.my_fragment, container, false);
      }
    
    
    
      // Called once the parent Activity and the Fragment's UI have 
      // been created.
      @Override
      public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        // Complete the Fragment initialization �particularly anything
        // that requires the parent Activity to be initialized or the 
        // Fragment's view to be fully inflated.
      }
    
      // Called at the start of the visible lifetime.
      @Override
      public void onStart(){
        super.onStart();
        // Apply any required UI change now that the Fragment is visible.
      }
    
      // Called at the start of the active lifetime.
      @Override
      public void onResume(){
        super.onResume();
        // Resume any paused UI updates, threads, or processes required
        // by the Fragment but suspended when it became inactive.
      }
    
      // Called at the end of the active lifetime.
      @Override
      public void onPause(){
        // Suspend UI updates, threads, or CPU intensive processes
        // that don't need to be updated when the Activity isn't
        // the active foreground activity.
        // Persist all edits or state changes
        // as after this call the process is likely to be killed.
        super.onPause();
      }
    
      // Called to save UI state changes at the
      // end of the active lifecycle.
      @Override
      public void onSaveInstanceState(Bundle savedInstanceState) {
        // Save UI state changes to the savedInstanceState.
        // This bundle will be passed to onCreate, onCreateView, and
        // onCreateView if the parent Activity is killed and restarted.
        super.onSaveInstanceState(savedInstanceState);
      }
    
      // Called at the end of the visible lifetime.
      @Override
      public void onStop(){
        // Suspend remaining UI updates, threads, or processing
        // that aren't required when the Fragment isn't visible.
        super.onStop();
      }
    
      // Called when the Fragment's View has been detached.
      @Override
      public void onDestroyView() {
        // Clean up resources related to the View.
        super.onDestroyView();
      }
    
      // Called at the end of the full lifetime.
      @Override
      public void onDestroy(){
        // Clean up any resources including ending threads,
        // closing database connections etc.
        super.onDestroy();
      }
    
      // Called when the Fragment has been detached from its parent Activity.
      @Override
      public void onDetach() {
        super.onDetach();
      }
    }

    生命周期要点:

    • 开始于绑定到它的你Activity,结束于从父Activity分离,对应于onAttach 和onDetach事件,通常情况下,onAttach用来获取一下Fragement的父Activity的引用,为进一步初始化做准备;
    • 不能依赖调用onDestroy方法来销毁它,因为此方面不定会被执行;
    • 与Activity一样,应该使用onCreate方法来初始化Fragement,在其生命周期内创建的作用域对象,且确保只创建一次;
    • 在onCreateView和onDestroyView上初始化和销毁UI;
    • 当Fragement暂停或停止时,保存所有的UI状态和持久化所有的数据。

    3,使用Fragement

    最佳实践是使用容器View来创建布局,将Fragement在运行时放入容器内

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="horizontal"
      android:layout_width="match_parent"
      android:layout_height="match_parent">
    
        <FrameLayout
            android:id="@+id/ui_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1" >
        </FrameLayout>
    
      <FrameLayout
        android:id="@+id/details_container"
        android:layout_width="match_parent" 
        android:layout_height="match_parent" 
        android:layout_weight="3"    
        android:visibility =”gone”    --隐藏
      />
    </LinearLayout>
     

    在运行时使用Fragement transaction来动态填充布局,从而当配置改变时,能确保一致性,框架代码如下:

    package com.paad.fragments;
    
    import android.app.Activity;
    import android.app.FragmentManager;
    import android.app.FragmentTransaction;
    import android.os.Bundle;
    
    public class MyFragmentActivity extends Activity {
    
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        // Inflate the layout containing the Fragment containers
        setContentView(R.layout.fragment_container_layout);
        
        FragmentManager fm = getFragmentManager();
    
        // Check to see if the Fragment back stack has been populated
        // If not, create and populate the layout.
        DetailsFragment detailsFragment = 
          (DetailsFragment)fm.findFragmentById(R.id.details_container);
        
        if (detailsFragment == null) {
           FragmentTransaction ft = fm.beginTransaction(); 
           ft.add(R.id.details_container, new DetailsFragment());
           ft.add(R.id.ui_container, new MyListFragment());
           ft.commit();
         }
      }
    }
    package com.paad.weatherstation;
    
    import com.paad.fragments.R;
    
    import android.app.Fragment;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    
    public class DetailsFragment extends Fragment {
      
      public DetailsFragment() {
      }
    
      // Called once the Fragment has been created in order for it to
      // create its user interface.
      @Override
      public View onCreateView(LayoutInflater inflater, 
                               ViewGroup container,
                               Bundle savedInstanceState) {
        // Create, or inflate the Fragment's UI, and return it. 
        // If this Fragment has no UI then return null.
        return inflater.inflate(R.layout.details_fragment, container, false);
      }
    }
    package com.paad.weatherstation;
    
    import com.paad.fragments.R;
    
    import android.annotation.SuppressLint;
    import android.app.Fragment;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    
    public class MyListFragment extends Fragment {
      
      public MyListFragment() {
      }
    
      // Called once the Fragment has been created in order for it to
      // create its user interface.
      @Override
      public View onCreateView(LayoutInflater inflater, 
                               ViewGroup container,
                               Bundle savedInstanceState) {
        // Create, or inflate the Fragment's UI, and return it. 
        // If this Fragment has no UI then return null.
        return inflater.inflate(R.layout.list_fragment, container, false);
      }
    }

    Fragement 和Activity之间的接口:

    • 任何Fragement中可使用getActivity方法返回对父Activity的引用;
    • 在fragement需要和它的主Activity共享事件的地方,最好在Fragement中创建回调接口,而主Activity必须实现它来监听Fragement中的改变;
    package com.paad.fragments;
    
    import android.app.Activity;
    import android.app.Fragment;
    
    /**
     * MOVED TO PA4AD_Ch04_Seasons
     */
    public class SeasonFragment extends Fragment {
    
      public interface OnSeasonSelectedListener {
        public void onSeasonSelected(Season season);
      }
        
      private OnSeasonSelectedListener onSeasonSelectedListener;
      private Season currentSeason;
    
      @Override
      public void onAttach(Activity activity) {
        super.onAttach(activity);
          
        try {
          onSeasonSelectedListener = (OnSeasonSelectedListener)activity;
        } catch (ClassCastException e) {
          throw new ClassCastException(activity.toString() + 
                    " must implement OnSeasonSelectedListener");
        }
      }
    
      private void setSeason(Season season) {
        currentSeason = season;
        onSeasonSelectedListener.onSeasonSelected(season);
      }
      
    }

    若理解有难道,可以了解一下JAVA编程思想中的上塑造型,内部类,接口方面的知识

  • 相关阅读:
    Linux文件管理系统
    添加硬盘分区
    SWPFILE实现(增加swap空间)
    磁盘配额
    javascript插件uploadify简单实现文件上传
    Java继承--子类的实例化过程
    Java继承--子父类中的构造函数
    Java继承--覆盖
    设计模式——单例设计模式
    在vim中,使用可视化拷贝(剪切)粘贴文本
  • 原文地址:https://www.cnblogs.com/mshwu/p/3266563.html
Copyright © 2011-2022 走看看