Android 保存Fragment 切换状态实例代码

前言

一般频繁切换Fragment会导致频繁的释放和创建,如果Fragment比较臃肿体验就非常不好了,这里分享一个方法。

 正文

 一、应用场景

1、不使用ViewPager

2、不能用replace来切换Fragment,会导致Fragment释放(调用onDestroyView)

 二、实现

1、xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical" >

 <FrameLayout
  android:id="@+id/container"
  android:layout_width="match_parent"
  android:layout_height="0dip"
  android:layout_weight="1.0" >
 </FrameLayout>

 <RadioGroup
  android:id="@+id/main_radio"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_gravity="bottom"
  android:gravity="bottom"
  android:layout_marginBottom="-6dp"
  android:orientation="horizontal" >

  <RadioButton
   android:id="@+id/radio_button0"
   style="@style/main_tab_bottom"
   android:drawableTop="@drawable/bottom_1" />

  <RadioButton
   android:id="@+id/radio_button1"
   style="@style/main_tab_bottom"
   android:drawableTop="@drawable/bottom_2" />

  <RadioButton
   android:id="@+id/radio_button2"
   style="@style/main_tab_bottom"
   android:drawableTop="@drawable/bottom_3" />

  <RadioButton
   android:id="@+id/radio_button3"
   style="@style/main_tab_bottom"
   android:drawableTop="@drawable/bottom_4" />

  <RadioButton
   android:id="@+id/radio_button4"
   style="@style/main_tab_bottom"
   android:drawableTop="@drawable/bottom_5" />
 </RadioGroup>

</LinearLayout>

代码说明:

非常常见的底部放5个RadioButton,点击切换不同的Fragment。

2、Activity

为RadioButton设置setOnCheckedChangeListener事件,其他代码:

 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
  if (isChecked) {
   Fragment fragment = (Fragment) mFragmentPagerAdapter.instantiateItem(mContainer, buttonView.getId());
   mFragmentPagerAdapter.setPrimaryItem(mContainer, 0, fragment);
   mFragmentPagerAdapter.finishUpdate(mContainer);
  }
 }

 private FragmentPagerAdapter mFragmentPagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {

  @Override
  public Fragment getItem(int position) {
   switch (position) {
   case R.id.radio_button1:
    return new Fragment1();
   case R.id.radio_button2:
    return new Fragment2();
   case R.id.radio_button3:
    return new Fragment3();
   case R.id.radio_button4:
    return new Fragment4();
   case R.id.radio_button0:
   default:
    return new Fragment0();
   }
  }

  @Override
  public int getCount() {
   return 5;
  }
 };

代码说明:

instantiateItem从FragmentManager中查找Fragment,找不到就getItem新建一个,setPrimaryItem设置隐藏和显示,最后finishUpdate提交事务, mContainer就是xml中的FrameLayout。

 三、FragmentPagerAdapter核心代码

 @Override
 public Object instantiateItem(ViewGroup container, int position) {
  if (mCurTransaction == null) {
   mCurTransaction = mFragmentManager.beginTransaction();
  }

  final long itemId = getItemId(position);

  // Do we already have this fragment?
  String name = makeFragmentName(container.getId(), itemId);
  Fragment fragment = mFragmentManager.findFragmentByTag(name);
  if (fragment != null) {
   if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
   mCurTransaction.attach(fragment);
  } else {
   fragment = getItem(position);
   if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
   mCurTransaction.add(container.getId(), fragment,
     makeFragmentName(container.getId(), itemId));
  }
  if (fragment != mCurrentPrimaryItem) {
   fragment.setMenuVisibility(false);
   fragment.setUserVisibleHint(false);
  }

  return fragment;
 }

 @Override
 public void destroyItem(ViewGroup container, int position, Object object) {
  if (mCurTransaction == null) {
   mCurTransaction = mFragmentManager.beginTransaction();
  }
  if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
    + " v=" + ((Fragment)object).getView());
  mCurTransaction.detach((Fragment)object);
 }

 @Override
 public void setPrimaryItem(ViewGroup container, int position, Object object) {
  Fragment fragment = (Fragment)object;
  if (fragment != mCurrentPrimaryItem) {
   if (mCurrentPrimaryItem != null) {
    mCurrentPrimaryItem.setMenuVisibility(false);
    mCurrentPrimaryItem.setUserVisibleHint(false);
   }
   if (fragment != null) {
    fragment.setMenuVisibility(true);
    fragment.setUserVisibleHint(true);
   }
   mCurrentPrimaryItem = fragment;
  }
 }

 @Override
 public void finishUpdate(ViewGroup container) {
  if (mCurTransaction != null) {
   mCurTransaction.commitAllowingStateLoss();
   mCurTransaction = null;
   mFragmentManager.executePendingTransactions();

}
 public void setMenuVisibility(boolean menuVisible) {        super.setMenuVisibility(menuVisible);        if (this.getView() != null)            this.getView().setVisibility(menuVisible ? View.VISIBLE : View.GONE);    }
 }

FragmentPagerAdapter是support包自带的类。

四、注意

之前自己模拟ViewPager用attach、setMenuVisibility、setUserVisibleHint来控制Fragment的显示隐藏,经常会出现Fragment重叠现象,非常头疼,换了这个之后目前没有发现重叠现象。

结束:以上就是对Android Fragment 实例说明,希望能帮助有需要的同学。

(0)

相关推荐

  • Android编程实现隐藏状态栏及测试Activity是否活动的方法

    本文实例讲述了Android编程实现隐藏状态栏及测试Activity是否活动的方法.分享给大家供大家参考,具体如下: 一. 隐藏状态栏 方法如下:在程序中加入//remove title 的那部分代码即可实现. package cn.edu.pku; import android.app.Activity; import android.os.Bundle; import android.view.Window; import android.view.WindowManager; public

  • android中Activity详解(生命周期、以各种方式启动Activity、状态保存,完全退出等)

    一.什么是Activity? 简单的说:Activity就是布满整个窗口或者悬浮于其他窗口上的交互界面.在一个应用程序中通常由多个Activity构成,都会在Manifestxml中指定一个主的Activity,如下设置 <actionandroid:name="AndroidintentactionMAIN" /> 当程序第一次运行时用户就会看这个Activity,这个Activity可以通过启动其他的Activity进行相关操作.当启动其他的Activity时这个当前的

  • Android学习小结之Activity保存和恢复状态

    Android中启动一个Activity如果点击Home键该Activity是不会被销毁的,但是当进行某些操作时某些数据就会丢失,如下: Java class: package com.king.activitytest2; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import

  • android初学者必须掌握的Activity状态的四大知识点(必读)

    这几天一直都在捣鼓android的知识点,兴趣班的老师,讲课太过深奥,天(想到什么就见什么,后后面完全不想听),最后自己找资料总结了在Android学习中很重要的一个组件Activity,那就开始吧! 第一:掌握Activity的四种状态及什么时候触发 首先我们要知道什么是Activity,简单来说Activity其实就是一个屏幕的显示页面.(简单的阐述) 我们知道Activity是由Activity栈进管理,当来到一个新的Activity后,此Activity将被加入到Activity栈顶,之

  • Android中监听软键盘显示状态实现代码

    /**监听软键盘状态 * @param activity * @param listener */ public static void addOnSoftKeyBoardVisibleListener(Activity activity, final OnSoftKeyBoardVisibleListener listener) { final View decorView = activity.getWindow().getDecorView(); decorView.getViewTree

  • 实例探究Android开发中Fragment状态的保存与恢复方法

    我们都知道,类似 Activity, Fragment 有 onSaveInstanceState() 回调用来保存状态. 在Fragment里面,利用onSaveInstanceState保存数据,并可在onActivityCreated里面恢复数据. public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); ... if (savedInsta

  • Android中用onSaveInstanceState保存Fragment状态的方法

    在Fragment里面,利用onSaveInstanceState保存数据,并可在onActivityCreated里面恢复数据. public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); ... if (savedInstanceState != null) { // Restore the fragment's state here } } p

  • Android保存Activity状态的方法

    本文实例讲述了Android保存Activity状态的方法.分享给大家供大家参考,具体如下: 如果你想保存Activity的信息(例如,类实例的变量)而又不需要和其它的组件共享的话,你可以调用Activity的getPreferences方法,不用指定一个Preference的名字.对返回的Shared  Preference的访问只限于调用的Activity:每个Activity支持一个不命名的Shared Preference对象. 下面的框架代码显示了如何使用Activity的私有Shar

  • Android中检查、监听电量和充电状态的方法

    当你在更改后台更新频率来减少这些更新对电池寿命的影响时,检查当前电量和充电状态是一个好的开始. 电池寿命通过剩余电量和充电状态来影响应用更新的执行.当用交流电充电时,执行更新操作对设备的影响是微不足道的,所以在大多数案例里,你可以把更新频率调到最快.如果设备不在充电,降低更新频率可以帮助延长电池寿命. 类似的,你可以检查电池剩余电量级别,在电量低时,应该降低更新频率甚至停止更新. 注:此处的更新,指的是类似发送心跳包的动作,或者定时更新内容.并非仅仅指更新应用版本.如果是用户动作,比如翻页刷新,

  • Android编程实现状态保存的方法分析

    本文实例讲述了Android编程实现状态保存的方法.分享给大家供大家参考,具体如下: 1.当我们正在发短信的时候,已经写了几百字了,这时突然来了一个电话,我们接完电话之后,如果发现辛辛苦苦的几百字不见了,那可就火大了,而实际上这些内容都是保存了的.在我们接电话的过程中,我们发信息的那个Activity是可能会被系统回收的,这时会调用Activity的onSaveInstanceState回调方法,而我们就可以在这个方法中保存状态数据,在onCreate方法或者在2.0之后提供的回调方法onRes

随机推荐