android Fragment实现Tab功能(fragment相互切换时,可保存之前状态)

原文转自 http://blog.csdn.net/jjsyjiao/article/details/40980909

由于TabHost已经逐渐过时,现在开发已经不建议使用,将由Fragment代替,本文主要讲述Fragment替换TabHost的方法,代码简单易懂,适合初学者使用。

上个效果图先:

      


首先:

1、建个资源文件activity_main.xml;

[html]  view plain  copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent" >  
  5.   
  6.   
  7.     <LinearLayout  
  8.         android:id="@+id/bottom"  
  9.         android:layout_width="match_parent"  
  10.         android:layout_height="60dip"  
  11.         android:layout_alignParentBottom="true"  
  12.         android:orientation="horizontal" >  
  13.   
  14.   
  15.         <RelativeLayout  
  16.             android:id="@+id/fotune"  
  17.             android:layout_width="0dip"  
  18.             android:layout_height="fill_parent"  
  19.             android:layout_weight="1"  
  20.             android:background="@color/bottom_background_onclick_color" >  
  21.   
  22.   
  23.             <ImageView  
  24.                 android:id="@+id/fotune_img"  
  25.                 android:layout_width="35dip"  
  26.                 android:layout_height="35dip"  
  27.                 android:layout_centerInParent="true"  
  28.                 android:background="@drawable/fotune_a" />  
  29.         RelativeLayout>  
  30.   
  31.   
  32.         <RelativeLayout  
  33.             android:id="@+id/message"  
  34.             android:layout_width="0dip"  
  35.             android:layout_height="fill_parent"  
  36.             android:layout_weight="1"  
  37.             android:background="@color/bottom_background_unclick_color" >  
  38.   
  39.   
  40.             <ImageView  
  41.                 android:id="@+id/message_img"  
  42.                 android:layout_width="35dip"  
  43.                 android:layout_height="35dip"  
  44.                 android:layout_centerInParent="true"  
  45.                 android:background="@drawable/message_ia" />  
  46.         RelativeLayout>  
  47.   
  48.   
  49.         <RelativeLayout  
  50.             android:id="@+id/account"  
  51.             android:layout_width="0dip"  
  52.             android:layout_height="fill_parent"  
  53.             android:layout_weight="1"  
  54.             android:background="@color/bottom_background_unclick_color" >  
  55.   
  56.   
  57.             <ImageView  
  58.                 android:id="@+id/account_img"  
  59.                 android:layout_width="35dip"  
  60.                 android:layout_height="35dip"  
  61.                 android:layout_centerInParent="true"  
  62.                 android:background="@drawable/account_ia" />  
  63.         RelativeLayout>  
  64.   
  65.   
  66.         <RelativeLayout  
  67.             android:id="@+id/more"  
  68.             android:layout_width="0dip"  
  69.             android:layout_height="fill_parent"  
  70.             android:layout_weight="1"  
  71.             android:background="@color/bottom_background_unclick_color" >  
  72.   
  73.   
  74.             <ImageView  
  75.                 android:id="@+id/more_img"  
  76.                 android:layout_width="35dip"  
  77.                 android:layout_height="35dip"  
  78.                 android:layout_centerInParent="true"  
  79.                 android:background="@drawable/more_ia" />  
  80.         RelativeLayout>  
  81.     LinearLayout>  
  82.   
  83.   
  84.     <FrameLayout  
  85.         android:id="@+id/container"  
  86.         android:layout_width="fill_parent"  
  87.         android:layout_height="match_parent"  
  88.         android:layout_above="@id/bottom" />  
  89.   
  90.   
  91. RelativeLayout>  

    其中FrameLayout就是承载着Fragment的容器;


2、接下来编写我们的Activity,注意:Activity需要继承FragmentActivity,不然调用getSupportFragmentManager()方法会提示“The method getSupportFragmentManager() is undefined for the type MainActivity”;

[java]  view plain  copy
  1. package com.example.tab;  
  2.   
  3.   
  4. import android.content.Context;  
  5. import android.os.Bundle;  
  6. import android.support.v4.app.Fragment;  
  7. import android.support.v4.app.FragmentActivity;  
  8. import android.support.v4.app.FragmentTransaction;  
  9. import android.view.View;  
  10. import android.view.View.OnClickListener;  
  11. import android.widget.ImageView;  
  12. import android.widget.RelativeLayout;  
  13.   
  14.   
  15. public class MainActivity extends FragmentActivity implements OnClickListener {  
  16.   
  17.   
  18.     public static Context context;  
  19.   
  20.   
  21.     private RelativeLayout fotune, message, account, more;  
  22.   
  23.   
  24.     private ImageView fotune_img, message_img, account_img, more_img;  
  25.   
  26.   
  27.     private Fragment1 fragment1 = new Fragment1();  
  28.   
  29.   
  30.     private Fragment2 fragment2 = new Fragment2();  
  31.   
  32.   
  33.     private Fragment3 fragment3 = new Fragment3();  
  34.   
  35.   
  36.     private Fragment4 fragment4 = new Fragment4();  
  37.   
  38.   
  39.     private Bundle bundle = new Bundle();  
  40.   
  41.   
  42.     /** 
  43.      * 记录当前Activity显示的fragment 
  44.      */  
  45.     private Fragment mContent;  
  46.   
  47.   
  48.     private String[] textStrings = new String[] { "第一个页面——Fragment1""第一个页面——Fragment2",  
  49.             "第一个页面——Fragment3""第一个页面——Fragment4" };  
  50.   
  51.   
  52.     @Override  
  53.     protected void onCreate(Bundle savedInstanceState) {  
  54.         super.onCreate(savedInstanceState);  
  55.         setContentView(R.layout.activity_main);  
  56.         context = MainActivity.this;  
  57.         initLayout();  
  58.         if (savedInstanceState == null) {  
  59.   
  60.   
  61.             bundle.putString("text", textStrings[0]);  
  62.             fragment1.setArguments(bundle);  
  63.             mContent = fragment1;  
  64.             getSupportFragmentManager().beginTransaction()  
  65.                     .add(R.id.container, fragment1).commit();  
  66.         }  
  67.     }  
  68.   
  69.   
  70.     /** 
  71.      * 初始化控件 
  72.      */  
  73.     private void initLayout() {  
  74.         fotune = (RelativeLayout) findViewById(R.id.fotune);  
  75.         fotune.setOnClickListener(this);  
  76.         message = (RelativeLayout) findViewById(R.id.message);  
  77.         message.setOnClickListener(this);  
  78.         account = (RelativeLayout) findViewById(R.id.account);  
  79.         account.setOnClickListener(this);  
  80.         more = (RelativeLayout) findViewById(R.id.more);  
  81.         more.setOnClickListener(this);  
  82.         fotune_img = (ImageView) findViewById(R.id.fotune_img);  
  83.         message_img = (ImageView) findViewById(R.id.message_img);  
  84.         account_img = (ImageView) findViewById(R.id.account_img);  
  85.         more_img = (ImageView) findViewById(R.id.more_img);  
  86.     }  
  87.   
  88.   
  89.     @Override  
  90.     public void onClick(View arg0) {  
  91.         // TODO Auto-generated method stub  
  92.   
  93.   
  94.         switch (arg0.getId()) {  
  95.         case R.id.fotune:  
  96.   
  97.   
  98.             fotune.setBackgroundColor(getResources().getColor(  
  99.                     R.color.bottom_background_onclick_color));  
  100.             message.setBackgroundColor(getResources().getColor(  
  101.                     R.color.bottom_background_unclick_color));  
  102.             account.setBackgroundColor(getResources().getColor(  
  103.                     R.color.bottom_background_unclick_color));  
  104.             more.setBackgroundColor(getResources().getColor(  
  105.                     R.color.bottom_background_unclick_color));  
  106.   
  107.   
  108.             fotune_img.setBackgroundDrawable(getResources().getDrawable(  
  109.                     R.drawable.fotune_a));  
  110.             message_img.setBackgroundDrawable(getResources().getDrawable(  
  111.                     R.drawable.message_ia));  
  112.             account_img.setBackgroundDrawable(getResources().getDrawable(  
  113.                     R.drawable.account_ia));  
  114.             more_img.setBackgroundDrawable(getResources().getDrawable(  
  115.                     R.drawable.more_ia));  
  116.   
  117.   
  118.             // switchContent(fragment1,  
  119.             // 0);若不想保留之前fragment的状态,每次都重新创建fragment,则选择该条命令;  
  120.             switchContent_keep(mContent, fragment1, 0);// 若想保留之前fragment的状态,则选择该条命令;  
  121.             break;  
  122.         case R.id.message:  
  123.   
  124.   
  125.             fotune.setBackgroundColor(getResources().getColor(  
  126.                     R.color.bottom_background_unclick_color));  
  127.             message.setBackgroundColor(getResources().getColor(  
  128.                     R.color.bottom_background_onclick_color));  
  129.             account.setBackgroundColor(getResources().getColor(  
  130.                     R.color.bottom_background_unclick_color));  
  131.             more.setBackgroundColor(getResources().getColor(  
  132.                     R.color.bottom_background_unclick_color));  
  133.   
  134.   
  135.             fotune_img.setBackgroundDrawable(getResources().getDrawable(  
  136.                     R.drawable.fotune_ia));  
  137.             message_img.setBackgroundDrawable(getResources().getDrawable(  
  138.                     R.drawable.message_a));  
  139.             account_img.setBackgroundDrawable(getResources().getDrawable(  
  140.                     R.drawable.account_ia));  
  141.             more_img.setBackgroundDrawable(getResources().getDrawable(  
  142.                     R.drawable.more_ia));  
  143.   
  144.   
  145.             // switchContent(fragment2,  
  146.             // 1);若不想保留之前fragment的状态,每次都重新创建fragment,则选择该条命令;  
  147.             switchContent_keep(mContent, fragment2, 1);// 若想保留之前fragment的状态,则选择该条命令;  
  148.             break;  
  149.         case R.id.account:  
  150.   
  151.   
  152.             fotune.setBackgroundColor(getResources().getColor(  
  153.                     R.color.bottom_background_unclick_color));  
  154.             message.setBackgroundColor(getResources().getColor(  
  155.                     R.color.bottom_background_unclick_color));  
  156.             account.setBackgroundColor(getResources().getColor(  
  157.                     R.color.bottom_background_onclick_color));  
  158.             more.setBackgroundColor(getResources().getColor(  
  159.                     R.color.bottom_background_unclick_color));  
  160.   
  161.   
  162.             fotune_img.setBackgroundDrawable(getResources().getDrawable(  
  163.                     R.drawable.fotune_ia));  
  164.             message_img.setBackgroundDrawable(getResources().getDrawable(  
  165.                     R.drawable.message_ia));  
  166.             account_img.setBackgroundDrawable(getResources().getDrawable(  
  167.                     R.drawable.account_a));  
  168.             more_img.setBackgroundDrawable(getResources().getDrawable(  
  169.                     R.drawable.more_ia));  
  170.   
  171.   
  172.             // switchContent(fragment3,  
  173.             // 2);若不想保留之前fragment的状态,每次都重新创建fragment,则选择该条命令;  
  174.             switchContent_keep(mContent, fragment3, 2);// 若想保留之前fragment的状态,则选择该条命令;  
  175.             break;  
  176.         case R.id.more:  
  177.   
  178.   
  179.             fotune.setBackgroundColor(getResources().getColor(  
  180.                     R.color.bottom_background_unclick_color));  
  181.             message.setBackgroundColor(getResources().getColor(  
  182.                     R.color.bottom_background_unclick_color));  
  183.             account.setBackgroundColor(getResources().getColor(  
  184.                     R.color.bottom_background_unclick_color));  
  185.             more.setBackgroundColor(getResources().getColor(  
  186.                     R.color.bottom_background_onclick_color));  
  187.   
  188.   
  189.             fotune_img.setBackgroundDrawable(getResources().getDrawable(  
  190.                     R.drawable.fotune_ia));  
  191.             message_img.setBackgroundDrawable(getResources().getDrawable(  
  192.                     R.drawable.message_ia));  
  193.             account_img.setBackgroundDrawable(getResources().getDrawable(  
  194.                     R.drawable.account_ia));  
  195.             more_img.setBackgroundDrawable(getResources().getDrawable(  
  196.                     R.drawable.more_a));  
  197.   
  198.   
  199.             // switchContent(fragment4,  
  200.             // 3);若不想保留之前fragment的状态,每次都重新创建fragment,则选择该条命令;  
  201.             switchContent_keep(mContent, fragment4, 3);// 若想保留之前fragment的状态,则选择该条命令;  
  202.             break;  
  203.         default:  
  204.             break;  
  205.         }  
  206.     }  
  207.   
  208.   
  209.     /** 
  210.      * fragment替换(不保留之前的状态) 
  211.      *  
  212.      * @param to 
  213.      * @param i 
  214.      */  
  215.     public void switchContent(Fragment to, int i) {  
  216.         bundle.putString("text", textStrings[i]);  
  217.         to.setArguments(bundle);  
  218.         getSupportFragmentManager().beginTransaction()  
  219.                 .replace(R.id.container, to).commit();  
  220.     }  
  221.   
  222.   
  223.     /** 
  224.      * fragment替换(保留之前的状态) 
  225.      *  
  226.      * @param from 
  227.      * @param to 
  228.      * @param i 
  229.      */  
  230.     public void switchContent_keep(Fragment from, Fragment to, int i) {  
  231.         if (from != to) {  
  232.             mContent = to;  
  233.             FragmentTransaction transaction = getSupportFragmentManager()  
  234.                     .beginTransaction();  
  235.             // 先判断是否被add过  
  236.             if (!to.isAdded()) {  
  237.                 bundle.putString("text", textStrings[i]);  
  238.                 to.setArguments(bundle);  
  239.                 // 隐藏当前的fragment,add下一个fragment到Activity中  
  240.                 transaction.hide(from).add(R.id.container, to).commit();  
  241.             } else {  
  242.                 // 隐藏当前的fragment,显示下一个fragment  
  243.                 transaction.hide(from).show(to).commit();  
  244.                 // to.onResume();该命令可注释,若希望fragment切换的过程中,被显示的fragment执行onResume方法,则解注;  
  245.   
  246.   
  247.             }  
  248.         }  
  249.   
  250.   
  251.     }  
  252. }  


如果在Fragment切换的过程中,不需要保留之前Fragment的状态,直接调用getSupportFragmentManager().beginTransaction().replace(R.id.Container, to).commit();即可。每次替换实质都是先remove再add,Fragment的onCreate方法都会被调用;

如果在Fragment切换的过程中,需要保留之前Fragment的状态,则需要定义一个变量Fragment mContent来保存当前activity显示fragment对象。如果你要显示的fragment对象之前未被添加过,则需要先隐藏当前显示的fragment对象,再添加你要显示的fragment对象;例如:transaction.hide(from).add(R.id.container, to).commit();若你要显示的fragment对象之前已经被添加过了,则先隐藏当前的fragment对象,再显示你要显示的fragment对象即可;例如:transaction.hide(from).show(to).commit();(注:如果此时希望调用显示的fragment对象的onResume方法,则执行to.onResume();即可。但注意的是:从fragmentActivity跳转到下一个Activity,再按返回键时,FrameLayout容器中所有的fragment都将会调用onResume方法;打印log如下所示:

[html]  view plain  copy
  1. 11-10 15:54:48.546: E/onCreate(19070): Fragment1  
  2. 11-10 15:54:48.546: E/onCreateView(19070): Fragment1  
  3. 11-10 15:54:48.546: E/onResume(19070): Fragment1  
  4. 11-10 15:54:49.936: E/onCreate(19070): Fragment2  
  5. 11-10 15:54:49.936: E/onCreateView(19070): Fragment2  
  6. 11-10 15:54:49.936: E/onResume(19070): Fragment2  
  7. 11-10 15:54:51.656: E/onCreate(19070): Fragment3  
  8. 11-10 15:54:51.656: E/onCreateView(19070): Fragment3  
  9. 11-10 15:54:51.656: E/onResume(19070): Fragment3  
  10. 11-10 15:54:52.806: E/onCreate(19070): Fragment4  
  11. 11-10 15:54:52.806: E/onCreateView(19070): Fragment4  
  12. 11-10 15:54:52.806: E/onResume(19070): Fragment4  
  13. <span style="color:#ff0000;">11-10 15:54:54.636: E/onResume(19070): Fragment1  
  14. 11-10 15:54:54.636: E/onResume(19070): Fragment2  
  15. 11-10 15:54:54.636: E/onResume(19070): Fragment3  
  16. 11-10 15:54:54.636: E/onResume(19070): Fragment4span>  


FragmentActivity向Fragment传递数据:创建个Bundle数据包,Fragment对象调用setArguments(Bundle bundle)方法即可;

Fragment接收从FragmentActivity传来的数据:调用getArguments()接收数据包,返回Bundle对象;


3、Fragment的具体实现

[java]  view plain  copy
  1. package com.example.tab;  
  2.   
  3.   
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.support.v4.app.Fragment;  
  7. import android.util.Log;  
  8. import android.view.LayoutInflater;  
  9. import android.view.View;  
  10. import android.view.ViewGroup;  
  11. import android.view.View.OnClickListener;  
  12. import android.widget.Button;  
  13. import android.widget.TextView;  
  14.   
  15.   
  16. public class Fragment1 extends Fragment {  
  17.   
  18.   
  19.     public Fragment1() {  
  20.     }  
  21.   
  22.   
  23.     @Override  
  24.     public void onCreate(Bundle savedInstanceState) {  
  25.         // TODO Auto-generated method stub  
  26.         super.onCreate(savedInstanceState);  
  27.         Log.e("onCreate""Fragment1");  
  28.     }  
  29.   
  30.   
  31.     @Override  
  32.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  33.             Bundle savedInstanceState) {  
  34.         Log.e("onCreateView""Fragment1");  
  35.         View rootView = inflater.inflate(R.layout.fragment_main, container,  
  36.                 false);  
  37.         TextView text = (TextView) rootView.findViewById(R.id.text);  
  38.         text.setText(getArguments().getString("text"));  
  39.         Button button = (Button) rootView.findViewById(R.id.button);  
  40.         button.setOnClickListener(new OnClickListener() {  
  41.   
  42.   
  43.             @Override  
  44.             public void onClick(View arg0) {  
  45.                 // TODO Auto-generated method stub  
  46.                 Intent intent = new Intent();  
  47.                 intent.setClass(MainActivity.context, SecondActivity.class);  
  48.                 startActivity(intent);  
  49.             }  
  50.   
  51.   
  52.         });  
  53.         return rootView;  
  54.     }  
  55.   
  56.   
  57.     @Override  
  58.     public void onResume() {  
  59.         // TODO Auto-generated method stub  
  60.         super.onResume();  
  61.         Log.e("onResume""Fragment1");  
  62.     }  
  63.   
  64.   
  65. }  

你可能感兴趣的:(android Fragment实现Tab功能(fragment相互切换时,可保存之前状态))