场景:使用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. atitit.极光消息推送服务器端开发实现推送  jpush v3. 总结o7p

    atitit.极光消息推送服务器端开发实现推送  jpush v3. 总结o7p 1. 推送所设计到底功能1 1.1. 内容压缩1 1.2. 多引擎1 2. reg  ,设置appkey and pw ...

  2. DM36x IPNC OSD显示中文 --- 基本数据准备篇

    经过上一篇的叙述,基本原理搞清楚后,便需要对我们在OSD上显示中文作数据准备,首先是需要将gb2312关键区(也就是实际有文字存在的区)中的汉字转换为图片,在实际的转换中,并不像上一篇中GB2312编 ...

  3. python 转化文件编码 utf8

    使用visual studio最大的一个问题就是文件编码问题,当文件中有中文时,visual studio 会默认为区域编码,也就是gb2312,如果想跨平台或者不用vs编译的话,就会因为编码问题导致 ...

  4. codeforces #363a Launch of Collider

    A. Launch of Collider time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  5. spring过滤器和拦截器的区别和联系

    一 简介 (1)过滤器: 依赖于servlet容器,是JavaEE标准,是在请求进入容器之后,还未进入Servlet之前进行预处理,并且在请求结束返回给前端这之间进行后期处理.在实现上基于函数回调,可 ...

  6. java -- 路径中包含空格怎么处理

    @.使用toURI()方法 String rootPath = this.getClass().getClassLoader().getResource(".").toURI(). ...

  7. 008android初级篇之jni中数组的传递

    008android初级篇之jni中数组的传递 jni中在native中数据类型的实际类型 jchar 占两个字节,跟native c中的char(占一个字节)是两个数据类型 jbyte, unsig ...

  8. [转]Netbeans IDE默认UTF-8编码

    NetBeans是一款优秀的开源集成开发环境,可以用于Java,C/C++,PHP等语言的开发.同时它也是一个可扩展的开发平台,可以通过插件来扩展官方版本没有的功能. NetBeans有一个很弱智的地 ...

  9. caffe使用自己的数据做分类

    这里只举一个例子: Alexnet网络训练自己数据的过程 用AlexNet跑自己的数据 参考1:http://blog.csdn.net/gybheroin/article/details/54095 ...

  10. day3笔记

    一.内容回顾 1.break:停止当前循环,后面的程序不会运行,跳出循环. 跳出while循环:1,改变条件.2.break continue:结束本次循环,继续下一次循环. 2.格式化输出:%%可以 ...