Fragment专辑的最后一篇,说明一下最常用的写法

来源:互联网 发布:淘宝卖家小卡片内容 编辑:程序博客网 时间:2024/05/03 16:13

今天是Fragment专辑的最后一篇,说明一下最常用的写法:

一般通过add、show、hide相结合的方法来控制Fragment的显示和隐藏,上一篇已经说过,这样不会再重写一遍Fragment的生命周期,节省了时间和内存,当然特殊需求除外。

贴出代码:

package com.example.lzp;import android.os.PersistableBundle;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentTransaction;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.RadioGroup;public class MainActivity extends FragmentActivity implements RadioGroup.OnCheckedChangeListener{    // 负责全局的FragmentManager, 建议使用support包中的FramengManager类    private FragmentManager fm;    private Fragment oneFragment, twoFragment, threeFragment;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        fm = getSupportFragmentManager();        RadioGroup tabRadio = (RadioGroup) findViewById(R.id.tab_radio);        tabRadio.setOnCheckedChangeListener(this);        if (oneFragment == null){            oneFragment = new OneFragment();        }        fm.beginTransaction().add(R.id.fragment_container, oneFragment).commit();    }    @Override    public void onCheckedChanged(RadioGroup group, int checkedId) {        FragmentTransaction transaction = fm.beginTransaction();        switch (checkedId){            case R.id.one:                // 判断是否为空                if (oneFragment == null){                    oneFragment = new OneFragment();                }                // 判断是否添加这个fragment对象是否已经添加到容器中                // 如果已经添加过了,就show,如果没有添加就add                if (oneFragment.isAdded()){                    transaction.show(oneFragment);                }else{                    transaction.add(R.id.fragment_container,oneFragment);                }                // 隐藏掉其他的两个fragment                if (twoFragment != null && twoFragment.isAdded()){                    transaction.hide(twoFragment);                }                if (threeFragment != null && threeFragment.isAdded()){                    transaction.hide(threeFragment);                }                break;            case R.id.two:                // 判断是否为空                if (twoFragment == null){                    twoFragment = new TwoFragment();                }                // 判断是否添加这个fragment对象是否已经添加到容器中                // 如果已经添加过了,就show,如果没有添加就add                if (twoFragment.isAdded()){                    transaction.show(twoFragment);                }else{                    transaction.add(R.id.fragment_container,twoFragment);                }                // 隐藏掉其他的两个fragment                if (oneFragment != null && oneFragment.isAdded()){                    transaction.hide(oneFragment);                }                if (threeFragment != null && threeFragment.isAdded()){                    transaction.hide(threeFragment);                }                break;            case R.id.three:                // 判断是否为空                if (threeFragment == null){                    threeFragment = new ThreeFragment();                }                // 判断是否添加这个fragment对象是否已经添加到容器中                // 如果已经添加过了,就show,如果没有添加就add                if (threeFragment.isAdded()){                    transaction.show(threeFragment);                }else{                    transaction.add(R.id.fragment_container,threeFragment);                }                // 隐藏掉其他的两个fragment                if (twoFragment != null && twoFragment.isAdded()){                    transaction.hide(twoFragment);                }                if (oneFragment != null && oneFragment.isAdded()){                    transaction.hide(oneFragment);                }                break;            default:                break;        }        transaction.commitAllowingStateLoss();    }    @Override    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {        super.onSaveInstanceState(outState, outPersistentState);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108

代码中已经写好了注释,就不再详细解释,很多初学的开发者认为写出上面的代码就可以了。实际上在功能是没有问题的,但是却有一个隐藏的巨大bug,假如MainActivity被回收,那也就说明MainActivity中所有的对象都被回收了,包括之前创建过的三个fragment,下次回到MainActivity的时候还会再创建一遍,判断是否已经添加过还是返回false,这样的情况出现多次,容器中就会添加了很多的同一类型的fragnment,最终出现内存溢出。

解决办法1: 
借助Activity的

 @Override    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {        super.onSaveInstanceState(outState, outPersistentState);    }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

这个方法会在activi回收的时候回调,可以重写这个方法保存一些我们想保存的信息,view的状态信息一般已经被自动保存了,不需要我们特意去写(实际测试锤子和坚果手机除外)。

outState.putSerializable(key, obj);outState.putParcelable(key, obj);
  • 1
  • 2
  • 1
  • 2

上面两个方法帮助我们保存对象,这个类必须实现可序列化接口,Android系统推荐的是使用第二个方法,还不了解如何使用这两个接口的少年可以去百度资料。

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        if (savedInstanceState != null){            obj = savedInstanceState.getSerializable(key);            obj = savedInstanceState.getParcelableArray(key);        }        ......    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

下次回到Activity的时候去判断是否有保存的信息,取出之前保存的对象即可。

解决办法2:

通过给fragment设置标签来保证容器中只有同一个类型的对象

 transaction.add(R.id.fragment_container,oneFragment, "oneFragment");
  • 1
  • 1

add方法中的第三个参数就是我们设置的标签,同一个类型我们设置一个唯一的标签,切换的时候通过标签获取对象:

FragmentManager fm = getSupportFragmentManager();oneFragment = fm.findFragmentByTag("oneFragment");if(one != null){    oneFragment = new OneFragment();}...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

我是使用的第二个方法,下面贴出第二种方法的完整代码:

package com.example.lzp;import android.os.PersistableBundle;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentTransaction;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.RadioGroup;public class MainActivity extends FragmentActivity implements RadioGroup.OnCheckedChangeListener{    // 负责全局的FragmentManager, 建议使用support包中的FramengManager类    private FragmentManager fm;    private Fragment oneFragment, twoFragment, threeFragment;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        fm = getSupportFragmentManager();        RadioGroup tabRadio = (RadioGroup) findViewById(R.id.tab_radio);        tabRadio.setOnCheckedChangeListener(this);        // 如果不需要恢复之前的状态,默认显示的是第一个oneFragment        if (savedInstanceState == null){            if (oneFragment == null){                oneFragment = new OneFragment();            }            fm.beginTransaction().add(R.id.fragment_container, oneFragment).commit();        }    }    @Override    public void onCheckedChanged(RadioGroup group, int checkedId) {        FragmentTransaction transaction = fm.beginTransaction();        switch (checkedId){            case R.id.one:                // 从容器通过标签获取相同类型的Fragment                oneFragment = fm.findFragmentByTag("OneFragment");                // 判断是否为空                if (oneFragment == null){                    oneFragment = new OneFragment();                }                // 判断是否添加这个fragment对象是否已经添加到容器中                // 如果已经添加过了,就show,如果没有添加就add                if (oneFragment.isAdded()){                    transaction.show(oneFragment);                }else{                    transaction.add(R.id.fragment_container,oneFragment, "OneFragment");                }                // 隐藏掉其他的两个fragment                if (twoFragment != null && twoFragment.isAdded()){                    transaction.hide(twoFragment);                }                if (threeFragment != null && threeFragment.isAdded()){                    transaction.hide(threeFragment);                }                break;            case R.id.two:                // 从容器通过标签获取相同类型的Fragment                twoFragment = fm.findFragmentByTag("TwoFragment");                // 判断是否为空                if (twoFragment == null){                    twoFragment = new TwoFragment();                }                // 判断是否添加这个fragment对象是否已经添加到容器中                // 如果已经添加过了,就show,如果没有添加就add                if (twoFragment.isAdded()){                    transaction.show(twoFragment);                }else{                    transaction.add(R.id.fragment_container,twoFragment, "TwoFragment");                }                // 隐藏掉其他的两个fragment                if (oneFragment != null && oneFragment.isAdded()){                    transaction.hide(oneFragment);                }                if (threeFragment != null && threeFragment.isAdded()){                    transaction.hide(threeFragment);                }                break;            case R.id.three:                // 从容器通过标签获取相同类型的Fragment                threeFragment = fm.findFragmentByTag("ThreeFragment");                // 判断是否为空                if (threeFragment == null){                    threeFragment = new ThreeFragment();                }                // 判断是否添加这个fragment对象是否已经添加到容器中                // 如果已经添加过了,就show,如果没有添加就add                if (threeFragment.isAdded()){                    transaction.show(threeFragment);                }else{                    transaction.add(R.id.fragment_container,threeFragment);                }                // 隐藏掉其他的两个fragment                if (twoFragment != null && twoFragment.isAdded()){                    transaction.hide(twoFragment);                }                if (oneFragment != null && oneFragment.isAdded()){                    transaction.hide(oneFragment);                }                break;            default:                break;        }        transaction.commitAllowingStateLoss();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114

xml:

<?xml version="1.0" encoding="utf-8"?><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"    tools:context="com.example.lzp.MainActivity"    android:orientation="vertical">    <FrameLayout        android:id="@+id/fragment_container"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1"/>    <RadioGroup        android:id="@+id/tab_radio"        android:layout_width="match_parent"        android:layout_height="50dp"        android:orientation="horizontal">        <RadioButton            android:id="@+id/one"            android:layout_width="0dp"            android:layout_weight="1"            android:layout_height="match_parent"            android:checked="true"            android:text="1"/>        <RadioButton            android:id="@+id/two"            android:layout_width="0dp"            android:layout_weight="1"            android:layout_height="match_parent"            android:text="2"/>        <RadioButton            android:id="@+id/three"            android:layout_width="0dp"            android:layout_weight="1"            android:layout_height="match_parent"            android:text="3"/>    </RadioGroup></LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

如果还有其他更加方便简单的方法,请大牛留言告知,让大家瞻仰学习一下。


1 0