Android中Fragment的Hide和Show

努力尽今夕,少年犹可夸。这篇文章主要讲述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吧:
我们要实现的就是这样一个效果:

Android中Fragment的Hide和Show

文章图片

其实不在网络上加载数据的话看不出来什么具体的效果,不过我们还是先看一下代码吧:
主页面的布局如下:
【Android中Fragment的Hide和Show】
1 < ?xml version="1.0" encoding="utf-8"?> 2 < LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3android:layout_width="match_parent" 4android:layout_height="match_parent" 5android:orientation="vertical" 6> 7 8< LinearLayout 9android:id="@+id/layout_main_fragment" 10android:layout_weight="1" 11android:layout_width="match_parent" 12android:layout_height="0dp" 13android:orientation="vertical"> 14 15< /LinearLayout> 16 17< RadioGroup 18android:id="@+id/rg" 19android:layout_width="match_parent" 20android:layout_height="wrap_content" 21android:gravity="center" 22android:layout_alignParentBottom="true" 23android:orientation="horizontal"> 24 25< RadioButton 26android:id="@+id/rb_tj" 27android:layout_width="0dp" 28android:layout_height="65dp" 29android:layout_weight="1" 30android:background="@drawable/rb_tuijian" 31android:button="@null" 32android:checked="true" /> 33 34< RadioButton 35android:id="@+id/rb_sj" 36android:layout_width="0dp" 37android:layout_height="65dp" 38android:layout_weight="1" 39android:background="@drawable/rb_shujia" 40android:button="@null" /> 41 42< RadioButton 43android:id="@+id/rb_fl" 44android:layout_width="0dp" 45android:layout_height="65dp" 46android:layout_weight="1" 47android:background="@drawable/rb_fenlei" 48android:button="@null" /> 49 50< RadioButton 51android:id="@+id/rb_gd" 52android:layout_width="0dp" 53android:layout_height="65dp" 54android:layout_weight="1" 55android:background="@drawable/rb_gengduo" 56android: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" 3android:layout_width="match_parent" 4android:layout_height="match_parent" 5android:orientation="vertical"> 6< TextView 7android:id="@+id/tv" 8android:layout_width="wrap_content" 9android:layout_height="wrap_content" 10android:textSize="25sp" 11android:textColor="@android:color/holo_red_light" 12android: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 18private TextView tv; 19 20@Nullable 21@Override 22public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 23View view = inflater.inflate(R.layout.fragment_page, null); 24tv = (TextView) view.findViewById(R.id.tv); 25Bundle bundle = getArguments(); 26int tag = bundle.getInt("tag"); 27switch (tag) { 28case 1: 29tv.setText("推荐"); 30break; 31case 2: 32tv.setText("书架"); 33break; 34case 3: 35tv.setText("分类"); 36break; 37case 4: 38tv.setText("更多"); 39break; 40} 41return 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 17private Fragment currentFragment=new Fragment(); 18private LinearLayout layout; 19private RadioButton rb_tj,rb_sj,rb_fl, rb_gd; 20private Fragment fragment_tj,fragment_sj,fragment_fl, fragment_gd; 21private FragmentManager manager; 22 23@Override 24protected void onCreate(Bundle savedInstanceState) { 25super.onCreate(savedInstanceState); 26setContentView(R.layout.activity_main); 27initView(); 28initFragment(); 29initEvent(); 30showFragment(fragment_tj); 31} 32 33/** 34* 初始化监听 35*/ 36private void initEvent() { 37rb_tj.setOnClickListener(this); 38rb_sj.setOnClickListener(this); 39rb_fl.setOnClickListener(this); 40rb_gd.setOnClickListener(this); 41} 42 43/** 44* 初始化Fragment 45*/ 46private void initFragment() { 47manager = getSupportFragmentManager(); 48 49Bundle bundle = new Bundle(); 50bundle.putInt("tag", 1); 51fragment_tj = new MyFragment(); 52fragment_tj.setArguments(bundle); 53 54bundle = new Bundle(); 55bundle.putInt("tag", 2); 56fragment_sj = new MyFragment(); 57fragment_sj.setArguments(bundle); 58 59bundle = new Bundle(); 60bundle.putInt("tag", 3); 61fragment_fl = new MyFragment(); 62fragment_fl.setArguments(bundle); 63 64bundle = new Bundle(); 65bundle.putInt("tag", 4); 66fragment_gd = new MyFragment(); 67fragment_gd.setArguments(bundle); 68} 69 70/** 71* 展示Fragment 72*/ 73private void showFragment(Fragment fragment) { 74if (currentFragment!=fragment) { 75FragmentTransaction transaction = manager.beginTransaction(); 76transaction.hide(currentFragment); 77currentFragment = fragment; 78if (!fragment.isAdded()) { 79transaction.add(R.id.layout_main_fragment, fragment).show(fragment).commit(); 80} else { 81transaction.show(fragment).commit(); 82} 83} 84} 85 86/** 87* 初始化控件 88*/ 89private void initView() { 90rb_tj = (RadioButton) findViewById(R.id.rb_tj); 91rb_sj = (RadioButton) findViewById(R.id.rb_sj); 92rb_fl = (RadioButton) findViewById(R.id.rb_fl); 93rb_gd = (RadioButton) findViewById(R.id.rb_gd); 94} 95 96@Override 97public void onClick(View v) { 98switch (v.getId()) { 99case R.id.rb_tj: 100showFragment(fragment_tj); 101break; 102case R.id.rb_sj: 103showFragment(fragment_sj); 104break; 105case R.id.rb_fl: 106showFragment(fragment_fl); 107break; 108case R.id.rb_gd: 109showFragment(fragment_gd); 110break; 111} 112} 113 }

可以看到,我们定义了一个全局Fragment,currentFragment,用来标示当前是哪一个Fragment。其中initFragment()方法只是为了初始化所有的Fragment,相信大家也看得出来,最主要的方法是showFragment(),下面我就来说一下这个方法:
1 /** 271* 展示Fragment 372*/ 473private void showFragment(Fragment fragment) { 574if (currentFragment!=fragment) { 675FragmentTransaction transaction = manager.beginTransaction(); 776transaction.hide(currentFragment); 877currentFragment = fragment; 978if (!fragment.isAdded()) { 1079transaction.add(R.id.layout_main_fragment, fragment).show(fragment).commit(); 1180} else { 1281transaction.show(fragment).commit(); 1382} 1483} 1584}

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

    推荐阅读