关闭

[置顶] Android 单Activity纯Fragment应用

791人阅读 评论(0) 收藏 举报
分类:

最近做了一个项目,要求全部使用Fragment去实现,就项目中的技术写点什么,希望帮助到大家:

Fragment简单的一些用法我也就不在啰嗦了,就捡终点的说:

1. 首先关于Fragment的初始化工作,我没有使用newInstance这种做法,而是在Activity加载的时候,统一做初始化Fragment fragment = new Fragment(),实际上跟newInstance实现的效果一样


2. 项目中的主页是4个Tab,每个Tab对应一个Fragment,我的布局是用RelativeLayout,底层是主页的布局,上边是单独的一个FrameLayout覆盖在上边,布局文件如下:

<RelativeLayout
    android:id="@+id/rootview"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#F7F4F2"
    android:orientation="vertical">

    <include android:id="@+id/title_layout" layout="@layout/activity_home_title_bar"/>

    <RadioGroup
        android:id="@+id/tab_radio_layout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@color/common_bgColor"
        android:orientation="horizontal"
        android:paddingBottom="2dp"
        android:paddingTop="2dp">

        <RadioButton
            android:id="@+id/order_btn"
            android:layout_width="0px"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:checked="true"
            android:drawablePadding="1dp"
            android:drawableTop="@drawable/selector_order_selected"
            android:gravity="center"
            android:text="信件"
            android:textSize="10dp"
            android:textColor="@drawable/selector_order_tx_selected"/>

        <RadioButton
            android:id="@+id/new_order_btn"
            android:layout_width="0px"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:checked="false"
            android:drawablePadding="1dp"
            android:drawableTop="@drawable/selector_newtast_selected"
            android:gravity="center"
            android:text="世界"
            android:textSize="10dp"
            android:textColor="@drawable/selector_order_tx_selected"/>

        <RadioButton
            android:textSize="10dp"
            android:id="@+id/record_order_btn"
            android:layout_width="0px"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:checked="false"
            android:drawablePadding="1dp"
            android:drawableTop="@drawable/selector_recorder_selected"
            android:gravity="center"
            android:text="社区"
            android:textColor="@drawable/selector_order_tx_selected"/>
    </RadioGroup>

    <FrameLayout
        android:layout_below="@+id/title_layout"
        android:id="@+id/fragment_content"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_above="@+id/tab_radio_layout"
       />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="0.5dp"
        android:layout_above="@+id/tab_radio_layout"
        android:background="#D1D1D1"/>

    <FrameLayout
        android:id="@+id/fragment_real_content"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
       />

</RelativeLayout>

3.主页的逻辑相信大家都会做,就说下页面跳转吧,我使用的add Fragment,同时addToBackStack(用途大家应该都知道,就是跟按下返回键的效果一样),代码如下
    public void switchDetailFragment(Fragment fragment, Bundle bundle) {
      
        if (fragment.isAdded()) {
            getSupportFragmentManager().beginTransaction().remove(fragment).commit();
        }
        fragment.setArguments(bundle);
        getSupportFragmentManager().beginTransaction().add(R.id.fragment_real_content, fragment,
                fragment.getClass().getSimpleName())
                .addToBackStack(fragment.getClass().getSimpleName())
                .commit();

    }
这里判断isAdded是为了防止Fragment重复加载抛异常,页面跳转就是这样,同时可以像Activity一样传参数

4. 关于Fragment的Back事件,如果主动调back方法也就是你有一个back button点击的话,那么你可以这样:

getActivity().getSupportFragmentManager().popBackStack()或者getActivity().onBackPressed()效果一样

5.关于Fragment回退栈管理:
 获取回退栈里的Fragment个数可以这样:
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
如果想获取回退栈顶层的Fragment可以这样:
String currentFragmentBackStack = getSupportFragmentManager().getBackStackEntryAt(backStackCount - 1).getName();
如果想做点击2次退出可以这样:
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
Log.d("onBackPressed", "onBackPressed backStackCount:" + backStackCount);
if (backStackCount <= 0) {
    if ((System.currentTimeMillis() - mExitTime) > 2000) {
        Toast.makeText(this, "再按一次,退出程序。", Toast.LENGTH_SHORT).show();
        mExitTime = System.currentTimeMillis();
    } else {
        finish();
    }
    return;
}
6.关于Fragment的回收问题:
我是判断Activity的
onCreate(Bundle savedInstanceState)里的savedInstanceState是否为空,然后做Fragment的remove操作,移除所有的Fragment,再重新加载Fragment
if(savedInstanceState != null ){
Fragment loginFragment = getSupportFragmentManager().findFragmentByTag("LoginFragment");
if (loginFragment != null) {
    getSupportFragmentManager().beginTransaction().remove(loginFragment).commit();
}
同上,吧所有的Fragment都remove掉,再重新走Activity的初始化方法

}

7. 解决Java.lang.IllegalStateException: Fragment already active
先把当前的fragment移除掉,保证栈中不存在多个fragment实例,然后重新new一个对象,再传递参数
Fragment already active
//这里也可以解决Fragment already added问题
if (fragment.isAdded()) {
    getSupportFragmentManager().beginTransaction().remove(fragment).commit();
}
if(fragment instanceof MailDetailFragment){
    fragment = new MailDetailFragment();
}
fragment.setArguments(bundle);

补充几个很重要的方法:
1. commit与commitAllowingStateLoss: 你只能在activity存储它的状态(当用户要离开activity时)之前调用commit(),如果在存储状态之后调用commit(),将会抛出一个异常。
 这是因为当activity再次被恢复时commit之后的状态将丢失。如果丢失也没关系,那么使用commitAllowingStateLoss()方法。

 其次FragmentTransaction是异步的,也就是说你commit或者commitAllowingStateLoss并不是立即执行的,如果想要立即执行这个等待中的操作,
 就要调用这个方法 getSupportFragmentManager().executePendingTransactions();

2. 处理Fragment isAdded跟Fragment already active异常:
    if (mTabFragment.isAdded()) {
        getSupportFragmentManager().beginTransaction().remove(mTabFragment).commitAllowingStateLoss();
        getSupportFragmentManager().executePendingTransactions();
        getSupportFragmentManager().beginTransaction().add(R.id.container,
            mTabFragment, mTabFragment.getClass().getSimpleName()).commitAllowingStateLoss();
    } else {
        getSupportFragmentManager().beginTransaction().add(R.id.container,
            mTabFragment, mTabFragment.getClass().getSimpleName()).commitAllowingStateLoss();
    }

好了,就讲到这里,感觉讲的不是很清楚,有问题可以给我留言,也可以加QQ756033860一起探讨。。

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:522006次
    • 积分:3546
    • 等级:
    • 排名:第9265名
    • 原创:48篇
    • 转载:0篇
    • 译文:0篇
    • 评论:114条
    文章分类
    最新评论