Android使用Fragment实现标签页
2015-09-22 22:44
471 查看
介绍
Fragment的概念是从Android3.0开始引入的,直译为碎片、片段,目的是为不同屏幕大小的设备(手机、平板等)创建灵活动态的UI。诚如其名,你可以把Fragment当作是Activity的模块化组件,它拥有自己的生命周期和UI,接受自身的处理事件,可以在Activity运行中被动态的添加、移除、替换。
Fragment必须被写成可重用的模块,你可以将多个Fragment组合到一个Activity中创建一个多模块界面,也可以在多个Activity中包含同一个Fragment的不同实例,这对于你的界面在不同屏幕尺寸下都能给用户完美的体验至关重要。
Fragment不能独立存在,它必须嵌入到Activity中,因此 Fragment的生命周期也依赖于Activity的生命周期,当其依赖的Activity的某个生命周期方法被调用时,该Activity下包含的所有Fragment的相应生命周期方法也将被调用,如onPause(),onStop(),onDestroy()等。官网示图很好地解释了两者的关系:
由上图可看到Fragment 比Activity多出了几个额外的生命周期。
onAttach():当Fragment对象与Activity关联时调用
onCreateView():用于创建和返回跟Fragment相关联的View对象
onActivityCreate():当Fragment所依附的Activity对象已经完成了onCreate()方法的执行
onDestoryView():清除跟Fragment的View对象相关联的资源
onDetach():当Fragment对象不再与其依附的Activity关联的时候调用
Fragment可以解决Activity间切换不流畅的问题,属于轻量切换。
Fragment替代TabHost做导航,性能更好。
Fragment做局部更新更方便,原先到达到这一点需要将多个布局放到一个Activity里,现在可以用多Fragment代替,只在需要的时候才加载Fragment,提高性能。
Fragment可以从startActivityForResult接收返回结果,但是View不能。
实现
一、使用Support Library
Support Library是一个提供了API函数的Jar文件,这样就可以在旧版本的Android上使用一些新的APIs;
这里我们要使用的是android-support-v4.jar文件,可以在Android SDK目录/extras/android/support/v4/路径下找到该文件,拷贝到项目的libs文件夹下即可。
二、创建几个继承Fragment的类,分别覆写onCreatView方法返回Fragment的布局。
inflate方法里三个参数的含义:
第一个参数是resource Id,指明了当前Fragment对应的布局文件;
第二个参数是父容器;
第三个布尔值参数是否连接该布局与其父容器,一般设为false,因为系统已经将该布局插入到了父控件,设为true会产生一个多余的ViewGroup。
布局文件如下,都只是简单包含一个TextView,不再重复写出:
三、创建MainAcitvity类,添加4个用于切换标签的按钮
布局文件如下,其中FrameLayout即为4个Fragment的父容器:
四、动态地添加、隐藏、显示Fragment
首先,需要获得一个FragmentTransaction(Fragment事务类)实例,可以在一个给定的事务中设置你想执行的所有变化,使用诸如 add(), remove(), 和 replace()等方法;然后, 要给Activity应用事务, 必须调用 commit()方法.
当选中某个按钮时,先隐藏所有不为空的Fragment标签页(仅仅是设为不见,并不会销毁)
再判断被选中的按钮对应的Fragment是否为空,如果为空则实例化该Fragment标签页并添加到Activity中;如果不为空,则直接显示之前被隐藏的该标签页。
效果
源码
http://download.csdn.net/detail/alfred_c/9131593
参考
http://www.cnblogs.com/mengdd/archive/2013/01/08/2851368.html http://zhidao.baidu.com/link?url=_7VMlAKu4cHz6PcfTMNrGJkM6ZUlK3_Hil2wre1WzcqFTe1neBXRq4gmRJOdVr3Iv_nWgCq4kyp61GIyv-exKLJuPQsGhuZIIaRnw62fF93
Fragment的概念是从Android3.0开始引入的,直译为碎片、片段,目的是为不同屏幕大小的设备(手机、平板等)创建灵活动态的UI。诚如其名,你可以把Fragment当作是Activity的模块化组件,它拥有自己的生命周期和UI,接受自身的处理事件,可以在Activity运行中被动态的添加、移除、替换。
Fragment必须被写成可重用的模块,你可以将多个Fragment组合到一个Activity中创建一个多模块界面,也可以在多个Activity中包含同一个Fragment的不同实例,这对于你的界面在不同屏幕尺寸下都能给用户完美的体验至关重要。
Fragment不能独立存在,它必须嵌入到Activity中,因此 Fragment的生命周期也依赖于Activity的生命周期,当其依赖的Activity的某个生命周期方法被调用时,该Activity下包含的所有Fragment的相应生命周期方法也将被调用,如onPause(),onStop(),onDestroy()等。官网示图很好地解释了两者的关系:
由上图可看到Fragment 比Activity多出了几个额外的生命周期。
onAttach():当Fragment对象与Activity关联时调用
onCreateView():用于创建和返回跟Fragment相关联的View对象
onActivityCreate():当Fragment所依附的Activity对象已经完成了onCreate()方法的执行
onDestoryView():清除跟Fragment的View对象相关联的资源
onDetach():当Fragment对象不再与其依附的Activity关联的时候调用
Fragment可以解决Activity间切换不流畅的问题,属于轻量切换。
Fragment替代TabHost做导航,性能更好。
Fragment做局部更新更方便,原先到达到这一点需要将多个布局放到一个Activity里,现在可以用多Fragment代替,只在需要的时候才加载Fragment,提高性能。
Fragment可以从startActivityForResult接收返回结果,但是View不能。
实现
一、使用Support Library
Support Library是一个提供了API函数的Jar文件,这样就可以在旧版本的Android上使用一些新的APIs;
这里我们要使用的是android-support-v4.jar文件,可以在Android SDK目录/extras/android/support/v4/路径下找到该文件,拷贝到项目的libs文件夹下即可。
二、创建几个继承Fragment的类,分别覆写onCreatView方法返回Fragment的布局。
public class DealFragment extends Fragment{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ return inflater.inflate(R.layout.fragment_deal, container, false); } }
public class PoiFragment extends Fragment{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ return inflater.inflate(R.layout.fragment_poi, container, false); } }
public class UserFragment extends Fragment{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ return inflater.inflate(R.layout.fragment_user, container, false); } }
public class MoreFragment extends Fragment{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ return inflater.inflate(R.layout.fragment_more, container, false); } }
inflate方法里三个参数的含义:
第一个参数是resource Id,指明了当前Fragment对应的布局文件;
第二个参数是父容器;
第三个布尔值参数是否连接该布局与其父容器,一般设为false,因为系统已经将该布局插入到了父控件,设为true会产生一个多余的ViewGroup。
布局文件如下,都只是简单包含一个TextView,不再重复写出:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="团购" android:textColor="#20B2AA" android:textSize="26sp" /> </RelativeLayout>
三、创建MainAcitvity类,添加4个用于切换标签的按钮
public class MainActivity extends FragmentActivity implements OnClickListener, FragmentConstants { private Button btnDeal; private Button btnPoi; private Button btnUser; private Button btnMore; private FragmentTransaction fragmentTransaction; private DealFragment dealFragments; private PoiFragment poiFragments; private UserFragment userFragments; private MoreFragment moreFragments; private int currentTabIndex = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews(); } private void initViews() { // TODO 自动生成的方法存根 btnDeal = (Button) findViewById(R.id.btn_deal); btnPoi = (Button) findViewById(R.id.btn_poi); btnUser = (Button) findViewById(R.id.btn_user); btnMore = (Button) findViewById(R.id.btn_more); btnDeal.setOnClickListener(this); btnPoi.setOnClickListener(this); btnUser.setOnClickListener(this); btnMore.setOnClickListener(this); setTabSelected(TAB_DEAL_INDEX); // 默认选中【团购】标签 } @Override public void onClick(View v) { // TODO 自动生成的方法存根 switch (v.getId()) { case R.id.btn_deal: setTabSelected(TAB_DEAL_INDEX); break; case R.id.btn_poi: setTabSelected(TAB_POI_INDEX); break; case R.id.btn_user: setTabSelected(TAB_USER_INDEX); break; case R.id.btn_more: setTabSelected(TAB_MORE_INDEX); break; } } private void setSelectedState(int i) { // TODO 自动生成的方法存根 switch (i) { case TAB_DEAL_INDEX: btnDeal.setSelected(true); break; case TAB_POI_INDEX: btnPoi.setSelected(true); break; case TAB_USER_INDEX: btnUser.setSelected(true); break; case TAB_MORE_INDEX: btnMore.setSelected(true); break; } } private void clearSelectedState() { // TODO 自动生成的方法存根 btnDeal.setSelected(false); btnPoi.setSelected(false); btnUser.setSelected(false); btnMore.setSelected(false); }
布局文件如下,其中FrameLayout即为4个Fragment的父容器:
<LinearLayout 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" android:orientation="vertical" > <FrameLayout android:id="@+id/content" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > </FrameLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#F5F5F5" android:orientation="horizontal" > <Button android:id="@+id/btn_deal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.25" android:background="@null" android:drawableTop="@drawable/tab_deal_img_selector" android:padding="5dp" android:text="团购" android:textColor="@drawable/tab_txt_selector" android:textSize="12sp" /> <Button android:id="@+id/btn_poi" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.25" android:background="@null" android:drawableTop="@drawable/tab_poi_img_selector" android:padding="5dp" android:text="商家" android:textColor="@drawable/tab_txt_selector" android:textSize="12sp" /> <Button android:id="@+id/btn_user" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.25" android:background="@null" android:drawableTop="@drawable/tab_user_img_selector" android:padding="5dp" android:text="我的" android:textColor="@drawable/tab_txt_selector" android:textSize="12sp" /> <Button android:id="@+id/btn_more" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.25" android:background="@null" android:drawableTop="@drawable/tab_more_img_selector" android:padding="5dp" android:text="更多" android:textColor="@drawable/tab_txt_selector" android:textSize="12sp" /> </LinearLayout> </LinearLayout>
四、动态地添加、隐藏、显示Fragment
首先,需要获得一个FragmentTransaction(Fragment事务类)实例,可以在一个给定的事务中设置你想执行的所有变化,使用诸如 add(), remove(), 和 replace()等方法;然后, 要给Activity应用事务, 必须调用 commit()方法.
fragmentTransaction = getSupportFragmentManager().beginTransaction();
当选中某个按钮时,先隐藏所有不为空的Fragment标签页(仅仅是设为不见,并不会销毁)
hideFragment(fragmentTransaction);
private void hideFragment(FragmentTransaction fragmentTransaction) { // TODO 自动生成的方法存根 if (dealFragments != null) fragmentTransaction.hide(dealFragments); if (poiFragments != null) fragmentTransaction.hide(poiFragments); if (userFragments != null) fragmentTransaction.hide(userFragments); if (moreFragments != null) fragmentTransaction.hide(moreFragments); }
再判断被选中的按钮对应的Fragment是否为空,如果为空则实例化该Fragment标签页并添加到Activity中;如果不为空,则直接显示之前被隐藏的该标签页。
switch (tabIndex) { case TAB_DEAL_INDEX: setSelectedState(TAB_DEAL_INDEX); if (dealFragments == null) { dealFragments = new DealFragment(); fragmentTransaction.add(R.id.content, dealFragments); } else { fragmentTransaction.show(dealFragments); } break; case TAB_POI_INDEX: setSelectedState(TAB_POI_INDEX); if (poiFragments == null) { poiFragments = new PoiFragment(); fragmentTransaction.add(R.id.content, poiFragments); } else { fragmentTransaction.show(poiFragments); } break; case TAB_USER_INDEX: setSelectedState(TAB_USER_INDEX); if (userFragments == null) { userFragments = new UserFragment(); fragmentTransaction.add(R.id.content, userFragments); } else { fragmentTransaction.show(userFragments); } break; case TAB_MORE_INDEX: setSelectedState(TAB_MORE_INDEX); if (moreFragments == null) { moreFragments = new MoreFragment(); fragmentTransaction.add(R.id.content, moreFragments); } else { fragmentTransaction.show(moreFragments); } break; } fragmentTransaction.commit(); // 该fragmentTransaction是全局变量,只能被commit一次
效果
源码
http://download.csdn.net/detail/alfred_c/9131593
参考
http://www.cnblogs.com/mengdd/archive/2013/01/08/2851368.html http://zhidao.baidu.com/link?url=_7VMlAKu4cHz6PcfTMNrGJkM6ZUlK3_Hil2wre1WzcqFTe1neBXRq4gmRJOdVr3Iv_nWgCq4kyp61GIyv-exKLJuPQsGhuZIIaRnw62fF93
相关文章推荐
- Android实现表情 抓取新浪表情
- 详解Android解析Xml的三种方式——DOM、SAX以及XMLpull
- android开发环境遇到adt无法启动的问题分析及解决方法
- Android开发 旋转屏幕导致Activity重建解决方法
- Android开发技巧之在a标签或TextView控件中单击链接弹出Activity(自定义动作)
- Android开发技巧之ViewStub控件惰性装载
- 分享10个很棒的学习Android开发的网站
- android开发之横向滚动/竖向滚动的ListView(固定列头)
- Android开发技巧之我的菜单我做主(自定义菜单)
- Windows下使用Apache Cordova开发ANDROID之HelloWorld
- 根据根据图片的url怎么取得图片ImageView对象
- [转] ADB server didn't ACK
- android开发的相关链接
- Android数据存储之SharedPreferences 共享首选项/偏好设置
- 基于NDK的Android防破解
- 麦子学院android开发笔记:Android更换RatingBar图片
- android开发入门知识之AIDL详解
- android开发学习如何一体化?从入门到高端开发的路如何走?
- Android入门到精通详解 电子书下载
- --暴走漫画系列--高仿淘宝收货地址(附demo)