场景:使用Fragment实现切页。

类结构:

  

一:Activity

Activity中使用getSupportFragmentManager().beginTransaction()来填充一个Fragment(管理用的FragmentA)

Activity部分代码:

FragmentA fragment = FragmentA.newInstant(null);
getSupportFragmentManager().beginTransaction().add(R.id.f_tab_fragment,fragment).commit();

XML:

            <FrameLayout
android:id="@+id/fl_container"
android:layout_width="match_parent"
android:layout_above="@+id/f_tab_fragment"
android:layout_height="match_parent"/> <FrameLayout
android:id="@+id/f_tab_fragment"
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_alignParentBottom="true"/>

二:FragmentA

加载一个主FragmentA,作为管理其它子叶片FragmentX。

现在比如有两个子叶片FragmentB、FragmentC.

FragmentA 使用FragmentManager和FragmentTransaction管理FragmentB、FragmentC的切换

FragmentA代码:

public class FragmentA extends BaseFragment {

    private static final String TAB_HOME = com.timediffproject.module.home.MyMainFragment.class.getName();

    private static final String TAB_TEST = com.timediffproject.module.home.TestFragment.class.getName();

    private BaseFragment mLastShowFragment;

    private static TabFragment fragment;

    public static TabFragment newInstant(Bundle bundle){
if (fragment == null){
fragment = new TabFragment();
fragment.setArguments(bundle);
}
return fragment;
} @Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initTabInfo(); } private void initTabInfo(){
FragmentManager fm = getFragmentManager();
if (fm == null){
return;
}
FragmentTransaction ft = fm.beginTransaction(); BaseFragment home = (BaseFragment) fm.findFragmentByTag(TAB_HOME);
if (home != null){
ft.hide(home);
} BaseFragment test = (BaseFragment) fm.findFragmentByTag(TAB_TEST);
if (test != null){
ft.hide(test);
} ft.commit(); } @Nullable
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tab,container,false);
} @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.btn_change_home).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
switchTo(TAB_HOME,null);
}
});
view.findViewById(R.id.btn_change_test).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
switchTo(TAB_TEST,null);
}
});
switchTo(TAB_HOME,null);
} //切换Fragment的方式(FragmentB、FragmentC)
//tab为Fragment的类名(如:FragmentB.class.getName())
//R.id.fl_container是在Activity的布局里,不是在FragmentA的布局里
private void switchTo(String tab, Bundle bundle){ //初始化管理Fragment的类
FragmentManager fm = getFragmentManager();
if (fm == null){
return;
}
FragmentTransaction ft = fm.beginTransaction(); //从FragmentManager里寻找类名为tab的Fragment
BaseFragment fragment = (BaseFragment)fm.findFragmentByTag(tab);
if (fragment == null){
fragment = (BaseFragment) Fragment.instantiate(getActivity(),tab);
fragment.setArguments(bundle);
ft.add(R.id.fl_container,fragment,tab);
}else{
ft.show(fragment);
}
//隐藏现在正显示的Fragment
if (mLastShowFragment != null) {
ft.hide(mLastShowFragment);
}
//记录最后点击的Fragment
mLastShowFragment = fragment; ft.commitAllowingStateLoss(); } }

XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="52dp"> <Button
android:id="@+id/btn_change_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="切换home"
/> <Button
android:id="@+id/btn_change_test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="切换test"
/> </LinearLayout>

三:FragmentX(FragmentB、FragmentC)

子页的逻辑根据具体业务自己定义,实现与一般Fragmeng一样

例如:

public class TestFragment extends BaseFragment {

    @Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_test,container,false);
} @Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
} }

到这里,就可以简单的实现-用底部Tab切换Fragment实现切页的功能

附图:

   

PS:实现过程中出现的错误

  java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

正确方式: 有关的fragment的初始化布局应该加上false,与父类布局建立关系。

原因:不加的话这个inflater出来的view系统会绑定一个未知父类,这时候当你把这个fragment又作为子页绑定给Activity或者另一个fragment时,就会出现以上错误。

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//这里正确的写法是:
//return inflater.inflate(R.layout.fragment_test,container,false);
return inflater.inflate(R.layout.fragment_test,container);
}

Android-实现切换Fragment页功能的更多相关文章

  1. Android 实现切换主题皮肤功能(类似于众多app中的 夜间模式,主题包等)

    首先来个最简单的一键切换主题功能,就做个白天和晚上的主题好了. 先看我们的styles文件: <resources> <!-- Base application theme. --& ...

  2. Android Studio精彩案例(二)《仿微信动态点击底部tab切换Fragment》

    转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 现在很多的App要么顶部带有tab,要么就底部带有tab.用户通过点击tab从而切换不同的页面(大部分情况时去切换fragment). ...

  3. Android Tab -- 使用Fragment、FragmentManager来实现

    原文地址:http://blog.csdn.net/crazy1235/article/details/42678877 效果: 代码:https://github.com/ldb-github/La ...

  4. Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信

    以下内容为原创,转载请注明:http://www.cnblogs.com/tiantianbyconan/p/3360938.html 如新浪微博下面的标签切换功能,我以前也写过一篇博文(http:/ ...

  5. Android使用Fragment来实现ViewPager的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信

    以下内容为原创,转载请注明:http://www.cnblogs.com/tiantianbyconan/p/3364728.html 我前两天写过一篇博客<Android使用Fragment来 ...

  6. Android - FragmentTabHost 与 Fragment 制作页面切换效果

    使用 FragmentTabHost 与 Fragment 制作页面切换效果 API 19 TabHost已经不建议使用了.用 FragmentTabHost 来代替TabHost.实际上 Fragm ...

  7. Android - TabHost 与 Fragment 制作页面切换效果

    Android - TabHost 与 Fragment 制作页面切换效果 Android API 19 , API 23 三个标签页置于顶端 效果图: 在文件BoardTabHost.java中定义 ...

  8. 【Android】保存Fragment切换状态

    前言 一般频繁切换Fragment会导致频繁的释放和创建,如果Fragment比较臃肿体验就非常不好了,这里分享一个方法. 声明 欢迎转载,但请保留文章原始出处:)  博客园:http://www.c ...

  9. Android应用切换皮肤功能实现

    原文地址:http://www.eoeandroid.com/thread-318159-1-1.html 现在大多数android应用都支持切换皮肤的功能.比如千千静听,墨迹天气等等.本文介绍两种切 ...

随机推荐

  1. FileNotFoundException: http:\localhos46087125.jpg (文件名、目录名或卷标语法不正确

    java.io.FileNotFoundException: http:\localhost:8080\ipms\upload\1332146087125.jpg (文件名.目录名或卷标语法不正确.) ...

  2. DataUml Design 教程3-模型与数据库同步

    上一节我们已经建立好了数据模型,那么怎么让数据模型和数据库进行同步呢?模型同步到数据库非常简单,只需要模型绑定到数据库即可.DataUml Design目前支持和Oracle与MS Server数据库 ...

  3. 【转】 详细介绍windows下使用python pylot进行网站压力测试

    windows下使用python进行网站压力测试,有两个必不可少的程序需要安装,一个是python,另一个是pylot.python是一个安装软件,用来运行python程序,而pylot则是pytho ...

  4. oracle中根据时间获取最新的一条数据

    order by kd.createtime 2.SELECT * FROM ( SELECT *,ROWNUM rn FROM t ORDER BY date_col DESC ) ,cg.bert ...

  5. 视觉SLAM之词袋(bag of words) 模型与K-means聚类算法浅析(2)

    聚类概念: 聚类:简单地说就是把相似的东西分到一组.同 Classification (分类)不同,分类应属于监督学习.而在聚类的时候,我们并不关心某一类是什么,我们需要实现的目标只是把相似的东西聚到 ...

  6. Ubuntu 下Apache安装和配置2

    在Ubuntu上安装Apache,有两种方式:1 使用开发包的打包服务,例如使用apt-get命令:2 从源码构建Apache.本文章将详细描述这两种不同的安装方式. 方法一:使用开发包的打包服务—— ...

  7. 双基准快速排序(Dual-Pivot Quicksort)(转)

    课本上常见的快速排序都是选择一个枢纽元(Pivot),基于这个枢纽元从前后双向扫描分成大于枢纽元和小于枢纽元的.而从JDK 7开始,java.util.Arrays.sort()使用双基准快速排序(D ...

  8. Assertion (software development) -- 断言

    Wiki: In computer programming, an assertion is a predicate (a true–false statement) placed in a prog ...

  9. SharePoint服务器端对象模型 之 访问文件和文件夹(Part 2)

    4.添加文件夹 文件夹的创建方法在文档库和普通列表中稍有不同. 在文档库中,与一般的集合操作相同,直接使用SPFolderCollection的Add(string name)方法即可添加文件夹,例如 ...

  10. cocos2d-x-3.1rc0中找不到"extensions/ExtensionMacros.h"的问题

    笔者导入UI编辑器的资源时,提示无法打开包括文件:“extensions/ExtensionMacros.h”: No such file or directory” 然后参考了3.0的一篇文章.得出 ...