【Android】FragmentTabHost实现底部Tab菜单选项

来源:互联网 发布:linux更改用户 编辑:程序博客网 时间:2024/05/20 23:58

以前实现类似微博底部菜单使用的是TabHost+Activity来实现,但是使用的时候提醒已经被弃用,现在我们可以通过FragmentTabHost+Fragment来实现。下面就是demo:

1.main_activity.xml 主布局文件。

<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/realtabcontent"          android:layout_width="match_parent"          android:layout_height="0dip"          android:layout_weight="1" />      <android.support.v4.app.FragmentTabHost        android:id="@android:id/tabhost"          android:layout_width="fill_parent"          android:layout_height="wrap_content">        <FrameLayout              android:id="@android:id/tabcontent"              android:layout_width="0dp"              android:layout_height="0dp"              android:layout_weight="0" />          </android.support.v4.app.FragmentTabHost></LinearLayout>

2.fragment_1.xml 这个文件是其中一个fragment的布局文件,有多少个fragment可以分别创建它们的xml文件,这个demo当中的4个fragment布局一样,所以共用一个xml文件

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <TextView        android:id="@+id/fragment_text"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textSize="80sp">    </TextView>        <EditText        android:id="@+id/fragment_edit"        android:layout_width="200dp"        android:layout_height="wrap_content">    </EditText></LinearLayout>

3.tab_item_view.xml  这个是Tab底部的每一个按钮的布局文件,显示了按钮的图标和对应文字

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:gravity="center"    android:orientation="vertical" >    <ImageView        android:id="@+id/imageview"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:focusable="false"        android:padding="3dp"         android:src="@drawable/ic_launcher">    </ImageView>    <TextView        android:id="@+id/textview"               android:layout_width="wrap_content"        android:layout_height="wrap_content"         android:text="首页"        android:textSize="12sp">    </TextView></LinearLayout>


4.tab_activity-btn.xml 设置按钮选中和不选中的照片,也是4个xml文件对应4个按钮,每个按钮两种状态,每种状态一张图片。

<?xml version="1.0" encoding="utf-8"?>  <selector xmlns:android="http://schemas.android.com/apk/res/android">        <item android:drawable="@drawable/ic_nav_one_sel" android:state_selected="true"/>      <item android:drawable="@drawable/ic_nav_one_nor"/>    </selector>


5.FragmentPage1.java,继承Fragment,用来管理其中的一个Tab的内容,demo底部有4个Tab,所以还创建了FragmentPage2.java,.FragmentPage3.java,.FragmentPage4.java

public class FragmentPage1 extends Fragment{  private EditText editText;private TextView textView;    @Override      public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {          System.out.println("onCreateView");         return inflater.inflate(R.layout.fragment_1, container, false);    }      @Overridepublic void onActivityCreated(Bundle savedInstanceState) {    super.onActivityCreated(savedInstanceState);    System.out.println("onActivityCreated");    editText = (EditText)getActivity().findViewById(R.id.fragment_edit);    textView = (TextView)getActivity().findViewById(R.id.fragment_text);   textView.setText("1");    }}  


6.MainActivity.java,继承了FragmentActivity,用来管理上一步的fragment。

public class MainActivity extends FragmentActivity {//定义FragmentTabHost对象      private FragmentTabHost mTabHost;            //定义一个布局      private LayoutInflater layoutInflater;                //定义数组来存放Fragment界面      private Class fragmentArray[] = {FragmentPage1.class,FragmentPage2.class,FragmentPage3.class,FragmentPage4.class};      //定义数组来存放按钮图片      private int mImageViewArray[] = {R.drawable.tab_activity_btn,R.drawable.tab_news_btn,R.drawable.tab_organization_btn,                                       R.drawable.tab_more_btn};            //Tab选项卡的文字      private String mTextviewArray[] = {"活动", "资讯", "组织", "更多"};       @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);           initView();   }     /**      * 初始化组件      */      private void initView(){          //实例化布局对象          layoutInflater = LayoutInflater.from(this);                            //得到TabHost          mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);        //实例化TabHost对象        mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);                     //得到fragment的个数          int count = fragmentArray.length;                               //循环添加Tab页        for(int i = 0; i < count; i++){                //为每一个Tab按钮设置tag和视图,newTabSpec的参数为tag标记,setIndicator设置Tab的显示视图            TabSpec tabSpec = mTabHost.newTabSpec(mTextviewArray[i]).setIndicator(getTabItemView(i));              //将Tab添加进FragmentTabHost中              mTabHost.addTab(tabSpec, fragmentArray[i], null);          }      }          /**      * 给Tab按钮设置图标和文字      */      private View getTabItemView(int index){          View view = layoutInflater.inflate(R.layout.tab_item_view, null);                ImageView imageView = (ImageView) view.findViewById(R.id.imageview);          imageView.setImageResource(mImageViewArray[index]);                    TextView textView = (TextView) view.findViewById(R.id.textview);                  textView.setText(mTextviewArray[index]);                return view;      }  }


7,优化:当我们在tab间切换时,之前fragment的布局会从新加载,我们看下fragment的生命周期,如下图:




我们在每次切换时,都会执行即将隐藏的fragment的onDestroyView()方法,准备显示的fragment的onCreateView方法。也就是每次切换时候都会从新加载布局,但是定义的全局变量并不会销毁(没有调用onDestroy方法),因此网上介绍的方式是用一个全局变量rootView来保存布局,切换fragment,会执行onCreateView()方法,我们就在里面判断rootView是否为空,不空即返回这个保存了的rootView即可,否则才从xml文件加载布局。添加生命周期打印函数以及优化后的fragment文件如下:

public class FragmentPage1 extends Fragment{  private EditText editText;private TextView textView;private View rootView;    @Override      public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {          System.out.println("onCreateView");    if(rootView == null){    rootView=inflater.inflate(R.layout.fragment_1, null);    }        //缓存的rootView需要判断是否已经被加过parent, 如果有parent需要从parent删除,要不然会发生这个rootview已经有parent的错误。          ViewGroup parent = (ViewGroup) rootView.getParent();          if (parent != null) {              parent.removeView(rootView);          }           return inflater.inflate(R.layout.fragment_1, container, false);    }          @Override    public void onAttach(Activity activity) {    super.onAttach(activity);    System.out.println("onAttach");    }        @Override    public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    System.out.println("onCreate");    }        @Overridepublic void onActivityCreated(Bundle savedInstanceState) {    super.onActivityCreated(savedInstanceState);    System.out.println("onActivityCreated");    editText = (EditText)getActivity().findViewById(R.id.fragment_edit);    textView = (TextView)getActivity().findViewById(R.id.fragment_text);   textView.setText("1");    }        @Override    public void onStart() {    super.onStart();    System.out.println("onStart");    }        @Override    public void onResume() {    super.onResume();    System.out.println("onResume");    }        @Override    public void onDestroy() {    super.onDestroy();    System.out.println("onDestroy");    }        @Override    public void onDestroyView() {    super.onDestroyView();    System.out.println("onDestroyView");    }    }  

运行效果如下:


0 0
原创粉丝点击