Android Fragment使用全解析

vn880254 8年前
   <p>Fragment的使用可谓是老生常谈了~~~</p>    <h2><strong>1、概述</strong></h2>    <p>自API 11引入Fragment之后,Fragment可谓风靡一时,现在大部分项目都或多或少的用到了Fragment,其更轻量级,更加适用屏幕,更加方便UI设计等优势。说了这么多什么是Fragment呢?</p>    <p>Fragment:碎片,碎片是一个应用程序的用户界面和行为能够被放置在一个活动上。在其核心,它代表了一个特定的操作或界面,运行在一个更大的活动上。代表界面是因为可作为View在布局中进行使用,代表特定操作是因为包含生命周期可进行逻辑操作。 简言之,Fragment就是一个带生命周期的组件。 (若有问题恳请指正!)</p>    <p>Fragment的特点:</p>    <ul>     <li>生命周期必须依赖于Activity, 当Activity被销毁,所有的碎片将被摧毁。(自己曾经踩坑)</li>     <li>轻量级,轻量切换。</li>     <li>方便处理平板、Phone的界面差异。</li>    </ul>    <h2><strong>2、继承结构和生命周期</strong></h2>    <p>继承结构:</p>    <p> </p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/8eab50b35107f44e5f49e1cc61ed3ab9.png"></p>    <p> </p>    <p>Fragment直接继承Object,有四个直接子类,我个人对它的子类使用甚少。</p>    <p>生命周期:</p>    <p> </p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/ad1abb9cf01a791b590d38eabc5e6f61.jpg"></p>    <p> </p>    <p>Fragment的生命周期在图上标注的很清楚了就不赘述了。该图是很久之前收藏的,已忘记原出处,在此感谢原作者!</p>    <h2><strong>3、基本使用</strong></h2>    <h3><strong>1.静态使用</strong></h3>    <p>静态使用就是Fragment相当于控件一样在布局中使用。</p>    <p>TestFragment.java 继承Fragment重写onCreateView方法</p>    <pre>  <code class="language-java">/**   * Created by magic on 2016年9月27日.   */  public class TestFragment extends Fragment {        @Override      public View onCreateView(LayoutInflater inflater, ViewGroup container,              Bundle savedInstanceState) {          View view = inflater.inflate(R.layout.fragment_main, container);          ImageView img=(ImageView)view.findViewById(R.id.img);          img.setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  Toast.makeText(getActivity(),"这是一个fragment", Toast.LENGTH_SHORT).show();              }          });          return view;      }    }</code></pre>    <p>fragment_main.xml</p>    <pre>  <code class="language-java"><RelativeLayout 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" >        <ImageView          android:id="@+id/img"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:layout_centerInParent="true"          android:src="@drawable/img" />    </RelativeLayout></code></pre>    <p>MainActivity.java 里面其实什么也没干。</p>    <pre>  <code class="language-java">/**   * Created by magic on 2016年9月27日.   */  public class MainActivity extends Activity {        @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);      }    }</code></pre>    <p>activity_main.xml</p>    <pre>  <code class="language-java"><RelativeLayout 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" >        <fragment          android:id="@+id/id_fragment"          android:layout_width="match_parent"          android:layout_height="match_parent"          class="com.magic.test_fragment.TestFragment" />    </RelativeLayout></code></pre>    <p>使用 fragment 标签添加碎片,通过class指定碎片的完整类名。</p>    <p>运行效果:</p>    <p> </p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/f40be433da6a001df3408a8cf994f550.gif"></p>    <p> </p>    <h3><strong>2.动态使用</strong></h3>    <p>动态使用就是向Fragment布局容器中动态添加、替换、移除、隐藏、显示Fragment。</p>    <p>CommonFragment.java</p>    <pre>  <code class="language-java">/**   * Created by magic on 2016年9月27日.通用Fragment   */  @SuppressLint("ValidFragment")   public class CommonFragment extends Fragment {        String desc;        public CommonFragment(String desc) {          super();          this.desc = desc;      }        @Override      public View onCreateView(LayoutInflater inflater, ViewGroup container,              Bundle savedInstanceState) {          View view = inflater.inflate(R.layout.fragment_common, container, false);          TextView tev = (TextView) view.findViewById(R.id.tev);          System.out.println(desc);          tev.setText(desc);          return view;      }    }</code></pre>    <p>通过构造方法传递数据的形式向TextView上设置内容。</p>    <p>fragment_common.xml</p>    <pre>  <code class="language-java"><?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"      android:orientation="vertical" >        <TextView          android:id="@+id/tev"          android:layout_width="match_parent"          android:layout_height="match_parent"          android:gravity="center"          android:textColor="@color/mainOrange" />    </LinearLayout></code></pre>    <p>MainActivity.java</p>    <pre>  <code class="language-java">/**   * Created by magic on 2016年9月27日.底部tab+fragment   */  public class MainActivity extends Activity implements OnClickListener {        TextView tev_tab1, tev_tab2, tev_tab3, tev_tab4;        // fragment事务类      FragmentTransaction ft;      // fragment      CommonFragment tabFragment1, tabFragment2, tabFragment3, tabFragment4;        @SuppressLint("CommitTransaction")      @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main2);          initView();            ft = getFragmentManager().beginTransaction();            tabFragment1 = new CommonFragment("Tab1");          // 替换          ft.replace(R.id.container, tabFragment1);          // 提交          ft.commit();      }        // 初始化控件      private void initView() {          tev_tab1 = (TextView) findViewById(R.id.tev_tab1);          tev_tab2 = (TextView) findViewById(R.id.tev_tab2);          tev_tab3 = (TextView) findViewById(R.id.tev_tab3);          tev_tab4 = (TextView) findViewById(R.id.tev_tab4);            tev_tab1.setOnClickListener(this);          tev_tab2.setOnClickListener(this);          tev_tab3.setOnClickListener(this);          tev_tab4.setOnClickListener(this);      }        @Override      public void onClick(View v) {            FragmentTransaction ft = getFragmentManager().beginTransaction();            switch (v.getId()) {          case R.id.tev_tab1:              ft.replace(R.id.container, tabFragment1);              break;          case R.id.tev_tab2:              if (tabFragment2 == null) {                  tabFragment2 = new CommonFragment("Tab2");              }              ft.replace(R.id.container, tabFragment2);              break;          case R.id.tev_tab3:              if (tabFragment3 == null) {                  tabFragment3 = new CommonFragment("Tab3");              }              ft.replace(R.id.container, tabFragment3);              break;          case R.id.tev_tab4:              if (tabFragment4 == null) {                  tabFragment4 = new CommonFragment("Tab4");              }              ft.replace(R.id.container, tabFragment4);              break;          }          // 提交          ft.commit();      }    }</code></pre>    <p>activity_main2.xml</p>    <pre>  <code class="language-java"><?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"      android:orientation="vertical" >        <FrameLayout          android:id="@+id/container"          android:layout_width="match_parent"          android:layout_height="0dp"          android:layout_weight="1" />        <LinearLayout          android:layout_width="match_parent"          android:layout_height="50dp"          android:background="@color/mainTextBlack"          android:orientation="horizontal" >            <TextView              android:id="@+id/tev_tab1"              android:layout_width="0dp"              android:layout_height="match_parent"              android:layout_weight="1"              android:gravity="center"              android:text="Tab1"              android:textColor="@color/white" />            <TextView              android:id="@+id/tev_tab2"              android:layout_width="0dp"              android:layout_height="match_parent"              android:layout_weight="1"              android:gravity="center"              android:text="Tab2"              android:textColor="@color/white" />            <TextView              android:id="@+id/tev_tab3"              android:layout_width="0dp"              android:layout_height="match_parent"              android:layout_weight="1"              android:gravity="center"              android:text="Tab3"              android:textColor="@color/white" />            <TextView              android:id="@+id/tev_tab4"              android:layout_width="0dp"              android:layout_height="match_parent"              android:layout_weight="1"              android:gravity="center"              android:text="Tab4"              android:textColor="@color/white" />      </LinearLayout>    </LinearLayout></code></pre>    <p>通过 FrameLayout 标签创建Fragment的容器,底部四个Tab添加监听事件用于动态更换FrameLayout容器中的Fragment。</p>    <p>运行效果:</p>    <p> </p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/98f00ed0bd8ece7a5a7a1782f671063f.gif"></p>    <p> </p>    <h2><strong>4、相关类及主要方法</strong></h2>    <p>FragmentManager碎片管理器,抽象类,具体实现在 Android -support-v4.jar中的FragmentManagerImpl类中。</p>    <pre>  <code class="language-java">// 获取FragmentManager对象          FragmentManager manager = getFragmentManager();</code></pre>    <p>FragmentTransaction碎片事务类,抽象类,具体实现在BackStackRecord类中。添加、删除、替换等操作其实最终的实现还是在FragmentManagerImpl类中。</p>    <pre>  <code class="language-java">// 获取FragmentTransaction对象          FragmentTransaction transaction = manager.beginTransaction();            // 添加fragment          transaction.add();          transaction.add(containerViewId, fragment, tag);          // 将被添加到容器的现有fragment替换          transaction.replace();          // 删除一个现有的fragment          transaction.remove();            // 保存当前fragment数据,避免视图重绘          transaction.hide();          // 显示以前隐藏的fragment          transaction.show();          // 这两个方法会触发fragment中的onHiddenChanged(boolean hidden)回调            // 显示之前数据 实例不会被销毁,但是视图层次依然会被销毁,即会调用onDestoryView和onCreateView          transaction.addToBackStack(null);          // 事务提交          transaction.commit();</code></pre>    <p>Fragment 碎片类</p>    <pre>  <code class="language-java">Fragment fragment = new Fragment();            // 返回此fragment当前关联的Activity          fragment.getActivity();          // 设置数据          fragment.setArguments(new Bundle());          // 获取数据          fragment.getArguments();          // 返回与该fragment作用的FragmentManager          fragment.getFragmentManager();          // 获取标签名          fragment.getTag();            // 当隐藏状态改变的时候回调          // onHiddenChanged(true);</code></pre>    <p>有兴趣大家可以去Read The Fucking Source,反正我看的比较头大…….</p>    <p> </p>    <p>来自:http://www.androidchina.net/5726.html</p>    <p> </p>