Android_Fragment

一. Fragment的简介

    Fragment在Android 3.0( API 11)引入,是为了支持在大屏上显示更加动态、灵活的UI,比如在平板和电视上。Fragment可以看作是嵌套的Activity,类似ActivityGroup,但是开销肯定没有ActivityGroup那么大,每一个Fragment管理着一个View,Fragment彼此之间相互独立,有自己的生命周期,这个生命周期是在Activity生命周期中的。Fragment可以用来解决屏幕适配和动态创建View的问题。

 

二.Fragment的生命周期

       Fragment必须是依存与Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期。

 

可以看到Fragment比Activity多了几个额外的生命周期回调方法:
onAttach(Activity)
       当Fragment与Activity发生关联时调用。
onCreateView(LayoutInflater,ViewGroup,Bundle)
       创建该Fragment的视图
onActivityCreated(Bundle)
       当Activity的onCreate方法返回时调用
onDestoryView()
       与onCreateView想对应,当该Fragment的视图被移除时调用
onDetach()
       与onAttach相对应,当Fragment与Activity关联被取消时调用
注意:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现!

 

 

三.Fragment常用的API

Fragment常用的三个类:

android.app.Fragment主要用于定义Fragment

 

android.app.FragmentManager主要用于在Activity中操作Fragment

 

   (1)获取FragmentManage的方式:getFragmentManager()// v4中,getSupportFragmentManager

 

   (2)使用findFragmentById() (用于在activity layout中提供一个UI的fragment)或findFragmentByTag()(适用于有或没有UI的fragment)获取activity中存在的fragment
   (3)将fragment从后台堆栈中弹出, 使用 popBackStack() (模拟用户按下BACK 命令).
   (4)使用addOnBackStackChangeListener()注册一个监听后台堆栈变化的listener.

 

 

android.app.FragmentTransaction每一个事务都是同时要执行的一套变化.可以在一个给定的事务中设置你想执行的所有变化,

FragmentTransaction的主要的操作方法

FragmentTransactiontransaction = fm.benginTransatcion();//开启一个事务

transaction.add() 

    往Activity中添加一个Fragment

transaction.remove()

    从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈,这个Fragment实例将会被销毁。

transaction.replace()

    使用另一个Fragment替换当前的,其实就是remove()然后add()

transaction.hide()

    隐藏当前的Fragment,仅仅是设为不可见,并不会销毁

transaction.show()

    显示之前隐藏的Fragment

detach()

    会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护。

attach()

    重建view视图,附加到UI上并显示。

transatcion.commit()//提交一个事务

注意:常用Fragment的哥们,可能会经常遇到这样Activity状态不一致:State loss这样的错误。主要是因为:commit方法一定要在Activity.onSaveInstance()之前调用。还有就是在一个事务开启到提交可以进行多个的添加、移除、替换等操作。

 

四.Fragment的使用

静态使用Fragment

 

        1.继承Fragment,重写onCreateView决定Fragemnt的布局(加载Fragment的布局)

         2.在Activity中声明此Fragment,就当和普通的View一样

       ( 注意:要给Fragment设置ID,要不无法初始化报错)

 

先看看布局:

 

 

静态使用Fragment的下载地址:http://download.csdn.net/detail/two_water/9279253

 

动态使用Fragment

1.效果图:

.

 

 

代码上主界面的代码,其他的想看就下载来看看:

 

[java] view plain copy
 
  1. <span style="font-size:12px;"><pre name="code" class="java">package com.liangdianshui.fragment2;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.FragmentManager;  
  5. import android.app.FragmentTransaction;  
  6. import android.os.Bundle;  
  7. import android.view.View;  
  8. import android.view.View.OnClickListener;  
  9. import android.widget.Button;  
  10. import android.widget.FrameLayout;  
  11.   
  12. public class MainActivity extends Activity implements OnClickListener {  
  13.   
  14.     private Button mBtNews;  
  15.     private Button mBtEntertainment;  
  16.     private Button mBtSports;  
  17.     private Button mBtInternational;  
  18.     private FrameLayout mContent;  
  19.     private MyFragmentNews frNews;  
  20.     private MyFragmentEntertainment myFragmentEntertainment;  
  21.     private MyFragmentInternational myFragmentInternational;  
  22.     private MyFragmentSports myFragmentSports;  
  23.   
  24.     @Override  
  25.     protected void onCreate(Bundle savedInstanceState) {  
  26.         super.onCreate(savedInstanceState);  
  27.         setContentView(R.layout.activity_main);  
  28.   
  29.         init();  
  30.   
  31.     }  
  32.   
  33.     private void init() {  
  34.         mContent = (FrameLayout) findViewById(R.id.fm_content);  
  35.         mBtNews = (Button) findViewById(R.id.bt_news);  
  36.         mBtEntertainment = (Button) findViewById(R.id.bt_entertainment);  
  37.         mBtSports = (Button) findViewById(R.id.bt_sports);  
  38.         mBtInternational = (Button) findViewById(R.id.bt_International);  
  39.         mBtNews.setOnClickListener(this);  
  40.         mBtEntertainment.setOnClickListener(this);  
  41.         mBtSports.setOnClickListener(this);  
  42.         mBtInternational.setOnClickListener(this);  
  43.         setDefaultContent();  
  44.     }  
  45.   
  46.     private void setDefaultContent() {  
  47.         FragmentManager fm = getFragmentManager();  
  48.         FragmentTransaction beginTransaction = fm.beginTransaction();  
  49.         frNews = new MyFragmentNews();  
  50.         beginTransaction.replace(R.id.fm_content, frNews);  
  51.         beginTransaction.commit();  
  52.     }  
  53.   
  54.     public void onClick(View view) {  
  55.         FragmentManager fm = getFragmentManager();  
  56.         FragmentTransaction beginTransaction = fm.beginTransaction();  
  57.         switch (view.getId()) {  
  58.         case R.id.bt_news:  
  59.             if (frNews == null) {  
  60.                 frNews = new MyFragmentNews();  
  61.             }  
  62.             beginTransaction.replace(R.id.fm_content, frNews);  
  63.             beginTransaction.commit();  
  64.             break;  
  65.         case R.id.bt_entertainment:  
  66.             if (myFragmentEntertainment == null) {  
  67.                 myFragmentEntertainment = new MyFragmentEntertainment();  
  68.             }  
  69.   
  70.             beginTransaction.replace(R.id.fm_content, myFragmentEntertainment);  
  71.             beginTransaction.commit();  
  72.             break;  
  73.         case R.id.bt_sports:  
  74.             if (myFragmentSports == null) {  
  75.                 myFragmentSports = new MyFragmentSports();  
  76.             }  
  77.             beginTransaction.replace(R.id.fm_content, myFragmentSports);  
  78.             beginTransaction.commit();  
  79.             break;  
  80.         case R.id.bt_International:  
  81.             if (myFragmentInternational == null) {  
  82.                 myFragmentInternational = new MyFragmentInternational();  
  83.             }  
  84.             beginTransaction.replace(R.id.fm_content, myFragmentInternational);  
  85.             beginTransaction.commit();  
  86.             break;  
  87.         default:  
  88.             break;  
  89.         }  
  90.     }  
  91.   
  92. }  
  93. </span>  

 

动态使用Fragment的Demo:http://download.csdn.net/detail/two_water/9279255

 

五.Fragment和Activity之间的通信

效果图和上面的都是一样的!只是考虑Fragment的重复使用,所以必须降低Fragment与Activity的耦合!虽然Fragment和Activity可以通过getActivity与findFragmentByTag或者findFragmentById,进行任何操作,甚至在Fragment里面操作另外的Fragment,但是没有特殊理由是不提倡的。Activity担任的是Fragment间类似总线一样的角色,应当由它决定Fragment如何操作。


 

因为效果图和上面的动态使用Fragment的效果图差不多!所以不上图了!

贴几个关键的代码:

 

[java] view plain copy
 
  1. package com.liangdianshui.fragment2;  
  2.   
  3. import android.app.Fragment;  
  4. import android.os.Bundle;  
  5. import android.view.LayoutInflater;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.view.ViewGroup;  
  9. import android.widget.Button;  
  10.   
  11. public class MyFragmentSports extends Fragment implements OnClickListener {  
  12.   
  13.     private Button bt_enter_news;  
  14.   
  15.     public interface enterNewsListener {  
  16.         void enterNewsOnClick();  
  17.     }  
  18.   
  19.     @Override  
  20.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  21.             Bundle savedInstanceState) {  
  22.         View view = inflater  
  23.                 .inflate(R.layout.fragment_sports, container, false);  
  24.         bt_enter_news = (Button) view.findViewById(R.id.bt_enter_news);  
  25.         bt_enter_news.setOnClickListener(this);  
  26.         return view;  
  27.     }  
  28.   
  29.     @Override  
  30.     public void onClick(View view) {  
  31.         if (getActivity() instanceof enterNewsListener) {  
  32.             ((enterNewsListener) getActivity()).enterNewsOnClick();  
  33.         }  
  34.     }  
  35. }  

 

 

[java] view plain copy
 
  1. package com.liangdianshui.fragment2;  
  2.   
  3. import com.liangdianshui.fragment2.MyFragmentSports.enterNewsListener;  
  4. import com.liangdianshui.fragment2.MyFragmentTitle.titleBtListener;  
  5.   
  6. import android.app.Activity;  
  7. import android.app.FragmentManager;  
  8. import android.app.FragmentTransaction;  
  9. import android.os.Bundle;  
  10. import android.view.View;  
  11. import android.view.View.OnClickListener;  
  12. import android.widget.Button;  
  13. import android.widget.FrameLayout;  
  14.   
  15. public class MainActivity extends Activity implements titleBtListener,  
  16.         enterNewsListener {  
  17.   
  18.     private FrameLayout mContent;  
  19.     private MyFragmentNews frNews;  
  20.     private MyFragmentEntertainment myFragmentEntertainment;  
  21.     private MyFragmentInternational myFragmentInternational;  
  22.     private MyFragmentSports myFragmentSports;  
  23.   
  24.     @Override  
  25.     protected void onCreate(Bundle savedInstanceState) {  
  26.         super.onCreate(savedInstanceState);  
  27.         setContentView(R.layout.activity_main);  
  28.         setDefaultContent();  
  29.     }  
  30.   
  31.     private void setDefaultContent() {  
  32.         FragmentManager fm = getFragmentManager();  
  33.         FragmentTransaction beginTransaction = fm.beginTransaction();  
  34.         frNews = new MyFragmentNews();  
  35.         beginTransaction.replace(R.id.fm_content, frNews);  
  36.         beginTransaction.commit();  
  37.     }  
  38.   
  39.     @Override  
  40.     public void titleOnClick(View view) {  
  41.         FragmentManager fm = getFragmentManager();  
  42.         FragmentTransaction beginTransaction = fm.beginTransaction();  
  43.         switch (view.getId()) {  
  44.         case R.id.bt_news:  
  45.             if (frNews == null) {  
  46.                 frNews = new MyFragmentNews();  
  47.             }  
  48.             beginTransaction.replace(R.id.fm_content, frNews);  
  49.             beginTransaction.commit();  
  50.             break;  
  51.         case R.id.bt_entertainment:  
  52.             if (myFragmentEntertainment == null) {  
  53.                 myFragmentEntertainment = new MyFragmentEntertainment();  
  54.             }  
  55.   
  56.             beginTransaction.replace(R.id.fm_content, myFragmentEntertainment);  
  57.             beginTransaction.commit();  
  58.             break;  
  59.         case R.id.bt_sports:  
  60.             if (myFragmentSports == null) {  
  61.                 myFragmentSports = new MyFragmentSports();  
  62.             }  
  63.             beginTransaction.replace(R.id.fm_content, myFragmentSports);  
  64.             beginTransaction.commit();  
  65.             break;  
  66.         case R.id.bt_International:  
  67.             if (myFragmentInternational == null) {  
  68.                 myFragmentInternational = new MyFragmentInternational();  
  69.             }  
  70.             beginTransaction.replace(R.id.fm_content, myFragmentInternational);  
  71.             beginTransaction.commit();  
  72.             break;  
  73.         default:  
  74.             break;  
  75.         }  
  76.     }  
  77.   
  78.     @Override  
  79.     public void enterNewsOnClick() {  
  80.         if (frNews == null) {  
  81.             frNews = new MyFragmentNews();  
  82.         }  
  83.         FragmentManager fm = getFragmentManager();  
  84.         FragmentTransaction beginTransaction = fm.beginTransaction();  
  85.         beginTransaction.replace(R.id.fm_content, frNews);  
  86.         beginTransaction.commit();  
  87.     }  
  88. }  



[java] view plain copy
 
  1. package com.liangdianshui.fragment2;  
  2.   
  3. import android.app.Fragment;  
  4. import android.os.Bundle;  
  5. import android.view.LayoutInflater;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.view.ViewGroup;  
  9. import android.widget.Button;  
  10.   
  11. public class MyFragmentTitle extends Fragment implements OnClickListener {  
  12.   
  13.     private Button mBtNews;  
  14.     private Button mBtEntertainment;  
  15.     private Button mBtSports;  
  16.     private Button mBtInternational;  
  17.   
  18.     public interface titleBtListener {  
  19.         void titleOnClick(View view);  
  20.     }  
  21.   
  22.     @Override  
  23.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  24.             Bundle savedInstanceState) {  
  25.         View view = inflater.inflate(R.layout.fragment_title, container, false);  
  26.         init(view);  
  27.         return view;  
  28.     }  
  29.   
  30.     private void init(View view) {  
  31.         mBtNews = (Button) view.findViewById(R.id.bt_news);  
  32.         mBtEntertainment = (Button) view.findViewById(R.id.bt_entertainment);  
  33.         mBtSports = (Button) view.findViewById(R.id.bt_sports);  
  34.         mBtInternational = (Button) view.findViewById(R.id.bt_International);  
  35.         mBtNews.setOnClickListener(this);  
  36.         mBtEntertainment.setOnClickListener(this);  
  37.         mBtSports.setOnClickListener(this);  
  38.         mBtInternational.setOnClickListener(this);  
  39.     }  
  40.   
  41.     @Override  
  42.     public void onClick(View view) {  
  43.         if (getActivity() instanceof titleBtListener) {  
  44.             ((titleBtListener) getActivity()).titleOnClick(view);  
  45.         }  
  46.     }  
  47.   
  48. }  

 

其中点击事件中的if(getActivity() instanceof titleBtListener)判断当前的activity是否实现了该接口~

Fragment和Activity通信Demo:http://download.csdn.net/detail/two_water/9279261

posted @ 2017-04-18 08:36  天涯海角路  阅读(118)  评论(0)    收藏  举报