Android中Fragment的Hide和Show

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android中Fragment的Hide和Show相关的知识,希望对你有一定的参考价值。

  我们都知道,Fragment动态添加的时候我们可以使用FragmentTransaction的add和replace方法,replace方法就等效于对这个Fragment先执行remove(),再执行add()。但是在实际的项目中,有很多时候我们会用到底部是一个RadioGroup包裹的RadioButton,上面用Fragment的情况,因为我们是从网络上获取的数据,这种时候我们不希望点击加载过的页面(也就是加载过的Fragment)的时候,每次都重新加载。也就是使用FragmentTransaction#replace()或者是add()方法行不通了,影响用户体验,这个时候就要用到FragmentTracsaction中的另两个方法了,也就是今天要提到的hide()和show()方法。这两个方法简单地说是会隐藏指定的Fragment,并不会销毁此Fragment,所以也就是可以保存下来之前在此Fragment中加载的数据了~。下面来看一下这个Demo吧:

  我们要实现的就是这样一个效果:

  技术分享

  其实不在网络上加载数据的话看不出来什么具体的效果,不过我们还是先看一下代码吧:

  主页面的布局如下:

 

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical"
 6     >
 7 
 8     <LinearLayout
 9         android:id="@+id/layout_main_fragment"
10         android:layout_weight="1"
11         android:layout_width="match_parent"
12         android:layout_height="0dp"
13         android:orientation="vertical">
14 
15     </LinearLayout>
16 
17     <RadioGroup
18         android:id="@+id/rg"
19         android:layout_width="match_parent"
20         android:layout_height="wrap_content"
21         android:gravity="center"
22         android:layout_alignParentBottom="true"
23         android:orientation="horizontal">
24 
25         <RadioButton
26             android:id="@+id/rb_tj"
27             android:layout_width="0dp"
28             android:layout_height="65dp"
29             android:layout_weight="1"
30             android:background="@drawable/rb_tuijian"
31             android:button="@null"
32             android:checked="true" />
33 
34         <RadioButton
35             android:id="@+id/rb_sj"
36             android:layout_width="0dp"
37             android:layout_height="65dp"
38             android:layout_weight="1"
39             android:background="@drawable/rb_shujia"
40             android:button="@null" />
41 
42         <RadioButton
43             android:id="@+id/rb_fl"
44             android:layout_width="0dp"
45             android:layout_height="65dp"
46             android:layout_weight="1"
47             android:background="@drawable/rb_fenlei"
48             android:button="@null" />
49 
50         <RadioButton
51             android:id="@+id/rb_gd"
52             android:layout_width="0dp"
53             android:layout_height="65dp"
54             android:layout_weight="1"
55             android:background="@drawable/rb_gengduo"
56             android:button="@null" />
57     </RadioGroup>
58 </LinearLayout>

这里用到了四个selector选择器作为RadioButton的背景,其他的没有什么,很简单的布局。当然,为了展示,我们还需要一个Fragment以及其对应的布局:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical">
 6     <TextView
 7         android:id="@+id/tv"
 8         android:layout_width="wrap_content"
 9         android:layout_height="wrap_content"
10         android:textSize="25sp"
11         android:textColor="@android:color/holo_red_light"
12         android:text="哈哈哈"/>
13 </LinearLayout>

由于只是一个小Demo,这里就没有写多个Fragment,而是复用了这一个Fragment,通过Fragment#setArgument(Bundle bundle)方法和getArgument()方法来复用该Fragment:

 1 package ggcomic.rabbit.lx.fragmenthideandshow.fragment;
 2 
 3 import android.os.Bundle;
 4 import android.support.annotation.Nullable;
 5 import android.support.v4.app.Fragment;
 6 import android.view.LayoutInflater;
 7 import android.view.View;
 8 import android.view.ViewGroup;
 9 import android.widget.TextView;
10 
11 import ggcomic.rabbit.lx.fragmenthideandshow.R;
12 
13 /**
14  * Created by Lx on 2016/9/20.
15  */
16 public class MyFragment extends Fragment {
17 
18     private TextView tv;
19 
20     @Nullable
21     @Override
22     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
23         View view = inflater.inflate(R.layout.fragment_page, null);
24         tv = (TextView) view.findViewById(R.id.tv);
25         Bundle bundle = getArguments();
26         int tag = bundle.getInt("tag");
27         switch (tag) {
28             case 1:
29                 tv.setText("推荐");
30                 break;
31             case 2:
32                 tv.setText("书架");
33                 break;
34             case 3:
35                 tv.setText("分类");
36                 break;
37             case 4:
38                 tv.setText("更多");
39                 break;
40         }
41         return view;
42     }
43 }

最主要的就是在MainActivity中的处理:

  1 package ggcomic.rabbit.lx.fragmenthideandshow.main;
  2 
  3 import android.support.v4.app.Fragment;
  4 import android.support.v4.app.FragmentManager;
  5 import android.support.v4.app.FragmentTransaction;
  6 import android.support.v7.app.AppCompatActivity;
  7 import android.os.Bundle;
  8 import android.view.View;
  9 import android.widget.LinearLayout;
 10 import android.widget.RadioButton;
 11 
 12 import ggcomic.rabbit.lx.fragmenthideandshow.R;
 13 import ggcomic.rabbit.lx.fragmenthideandshow.fragment.MyFragment;
 14 
 15 public class MainActivity extends AppCompatActivity implements View.OnClickListener {
 16 
 17     private Fragment currentFragment=new Fragment();
 18     private LinearLayout layout;
 19     private RadioButton rb_tj,rb_sj,rb_fl, rb_gd;
 20     private Fragment fragment_tj,fragment_sj,fragment_fl, fragment_gd;
 21     private FragmentManager manager;
 22 
 23     @Override
 24     protected void onCreate(Bundle savedInstanceState) {
 25         super.onCreate(savedInstanceState);
 26         setContentView(R.layout.activity_main);
 27         initView();
 28         initFragment();
 29         initEvent();
 30         showFragment(fragment_tj);
 31     }
 32 
 33     /**
 34      * 初始化监听
 35      */
 36     private void initEvent() {
 37         rb_tj.setOnClickListener(this);
 38         rb_sj.setOnClickListener(this);
 39         rb_fl.setOnClickListener(this);
 40         rb_gd.setOnClickListener(this);
 41     }
 42 
 43     /**
 44      * 初始化Fragment
 45      */
 46     private void initFragment() {
 47         manager = getSupportFragmentManager();
 48 
 49         Bundle bundle = new Bundle();
 50         bundle.putInt("tag", 1);
 51         fragment_tj = new MyFragment();
 52         fragment_tj.setArguments(bundle);
 53 
 54         bundle = new Bundle();
 55         bundle.putInt("tag", 2);
 56         fragment_sj = new MyFragment();
 57         fragment_sj.setArguments(bundle);
 58 
 59         bundle = new Bundle();
 60         bundle.putInt("tag", 3);
 61         fragment_fl = new MyFragment();
 62         fragment_fl.setArguments(bundle);
 63 
 64         bundle = new Bundle();
 65         bundle.putInt("tag", 4);
 66         fragment_gd = new MyFragment();
 67         fragment_gd.setArguments(bundle);
 68     }
 69 
 70     /**
 71      * 展示Fragment
 72      */
 73     private void showFragment(Fragment fragment) {
 74         if (currentFragment!=fragment) {
 75             FragmentTransaction transaction = manager.beginTransaction();
 76             transaction.hide(currentFragment);
 77             currentFragment = fragment;
 78             if (!fragment.isAdded()) {
 79                 transaction.add(R.id.layout_main_fragment, fragment).show(fragment).commit();
 80             } else {
 81                 transaction.show(fragment).commit();
 82             }
 83         }
 84     }
 85 
 86     /**
 87      * 初始化控件
 88      */
 89     private void initView() {
 90         rb_tj = (RadioButton) findViewById(R.id.rb_tj);
 91         rb_sj = (RadioButton) findViewById(R.id.rb_sj);
 92         rb_fl = (RadioButton) findViewById(R.id.rb_fl);
 93         rb_gd = (RadioButton) findViewById(R.id.rb_gd);
 94     }
 95 
 96     @Override
 97     public void onClick(View v) {
 98         switch (v.getId()) {
 99             case R.id.rb_tj:
100                 showFragment(fragment_tj);
101                 break;
102             case R.id.rb_sj:
103                 showFragment(fragment_sj);
104                 break;
105             case R.id.rb_fl:
106                 showFragment(fragment_fl);
107                 break;
108             case R.id.rb_gd:
109                 showFragment(fragment_gd);
110                 break;
111         }
112     }
113 }

可以看到,我们定义了一个全局Fragment,currentFragment,用来标示当前是哪一个Fragment。其中initFragment()方法只是为了初始化所有的Fragment,相信大家也看得出来,最主要的方法是showFragment(),下面我就来说一下这个方法:

 1 /**
 2  71      * 展示Fragment
 3  72      */
 4  73     private void showFragment(Fragment fragment) {
 5  74         if (currentFragment!=fragment) {
 6  75             FragmentTransaction transaction = manager.beginTransaction();
 7  76             transaction.hide(currentFragment);
 8  77             currentFragment = fragment;
 9  78             if (!fragment.isAdded()) {
10  79                 transaction.add(R.id.layout_main_fragment, fragment).show(fragment).commit();
11  80             } else {
12  81                 transaction.show(fragment).commit();
13  82             }
14  83         }
15  84     }

这个方法主要完成Fragment的隐藏和展示,也就是完成Fragment的切换功能。可以看到,在方法的开始我们先判断一下传入的Fragment是不是当前currentFragment,如果不是的话,我们就隐藏currentFragment,并且将我们传入的Fragment赋值给currentFragment。然后再调用Fragment#isAdded()方法,判断传入的Fragment是否已经被add()过了,如果已经被add()过了,那么就直接FragmentTransaction#show()并且commit()即可,否则的话先add()当前fragment,然后在show()展示出来。这样我们就成功实现了保存加载过的Fragment中的内容了(其实不算保存,只是不让加载过的内容销毁),是不是很简单呢?快下一个小Demo尝试一下吧~

以上是关于Android中Fragment的Hide和Show的主要内容,如果未能解决你的问题,请参考以下文章

Android Dialog hide()、cancel()一起使用,show()无效问题

FragmentTransaction的add(),replace(),以及show(),hide()

Android 保存 Fragment 引用及 getActivity() 为空问题

Android 保存 Fragment 引用及 getActivity() 为空问题

Fragment 使用hide和show,使用onHiddenChanged代替执行生命周期

android 切换fragment的两种方式