0

我有我的主要活动 actionbaractivity One,您可以在其中通过一些片段进行屏幕滑动,在每个片段上您都有一个imageView和一个ListView,您可以在其中单击任何项​​目并且图像会改变。同样在菜单选项中,您有一个按钮,您可以在其中更改为几乎完全相同的活动: actiobbaractivity 两个也有此按钮可以更改为活动一个 我能够做的是在滑动片段时保留图像,但无法通过活动的变化保持碎片状态。

例如,我在片段 3 上的活动一中使用图像:“某物”。我单击按钮更改为活动二,我在此处执行操作,然后单击按钮更改为活动一,我想查看带有图像的片段 3:“某物”而不是默认片段 1 和默认图片

我为每个活动使用 ActionBarActivity、FragmentStatePagerAdapter 和 Fragment

谢谢您的帮助

4

1 回答 1

0

根据 Activity 和 Fragment 生命周期(http://developer.android.com/reference/android/app/Activity.html#ActivityLifecyclehttp://developer.android.com/guide/components/fragments.html#Lifecycle) ,在活动/片段更改之间保持状态的最可靠方法是使用默认 API 来保存和恢复状态:

当 Activity/Fragment 被关闭时(由于屏幕旋转等配置更改或因为用户请求转到另一个 Activity/Fragment),您可以将其状态保存在 Bundle 对象中。在创建它时,您可以恢复其保存的状态,从而重新创建一个与用户离开的实例完全相同的新实例 - 因此用户感觉没有任何变化。这不取决于您正在使用的活动/片段的特定子类。

我已经实现了你想要的东西:在我的例子中,一个片段包含一个带有按钮的菜单,每个按钮将用户引导到另一个片段,其中包含一个带有“后退”按钮的子菜单。因此,如果用户从菜单转到子菜单 1,然后返回菜单,然后返回子菜单 2,然后返回菜单,最后再次返回子菜单 1,我希望子菜单 1 看起来就像用户第一次离开它一样.

为此,我创建了:

1)通过我的活动interface定义我的子菜单类型,implemented以便它们可以在我的子菜单之间更改

2)一个主通用class,我所有的子菜单都会extend有一个Bundle对象来存储它们的状态

3)在我的活动中,我有一组Bundle能够存储每个子菜单的一个实例(因为我只对恢复最后一个状态感兴趣,所以我不需要多个)

接口(项目1):

    public interface SubmenusManager {
      public static enum Submenus {
        ROOTMENU, 
        SUBMENU1,
        SUBMENU2;

        private static final int size = Submenus.values().length;
        public static int size() {
          return size;
        }
        public static int getId(Submenus test) {
          switch(test) {
            case SUBMENU1: 
              return 1;

            case SUBMENU2: 
              return 2;

            case ROOTMENU: 
            default:    
              return 0;
          }
        }
      }

      public void cloneCurrentSubmenuState(Parcelable toOverwrite);
      public Bundle getLastStoredSubmenuState(Submenus submenu);
      public void setCurrentSubmenuTo(Submenus submenu);
    }

泛型类(第 2 项):

    public class MenuFragment extends Fragment {
      private Bundle menuData = new Bundle();
      public static String RESTORE_MAIN_OBJECT = "restore_main";

      public Bundle getMenuData() {
        return menuData;
      }
      public Bundle cloneMenuData() {
        return new Bundle(menuData);
      }

      public void setMenuData(Bundle menuData) {
        this.menuData = menuData;
      }
    }

其中一项活动(第 3 项):

    public class ExampleAct extends FragmentActivity implements SubmenusManager {
      /**
      * instance variables
      */
      private MenuFragment mMenu; 
      private Bundle [] menuData; //  the Array of Bundles!
      private static final String CONTAINER = "parcelable_container";

      private static final String SUBMENU = "saved_submenu";
      private Submenus curSubmenu = Submenus.ROOTMENU; // the default state is the ROOTMENU
      private boolean restoreLastSavedState = false;

      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState == null) { // first time creating this activity
          menuData = new Bundle[Submenus.size()];
        } else { // this activity has a saved state from before
          // restore all the data from all the submenus
          menuData = (Bundle[]) savedInstanceState.getParcelableArray(CONTAINER);
          // restore the info about which is the current active submenu
          curSubmenu = (Submenus) savedInstanceState.getSerializable(SUBMENU);
        }

        buildMenuFragment(true);

        //(...) stuff
      }

      private void buildMenuFragment(boolean restoreState) {
        // (re)builds fragment inside menu. 
        // restoreState flags whether activity should look for
        // saved state data and restore it
        restoreLastSavedState = restoreState;
        switch(curSubmenu) { 
          // Eclipse warns you about which are the constants in your enum
          case ROOTMENU:
            mMenu = new FragmentRootMenu();
            break;
          case SUBMENU1:
            mMenu = new FragmentSubmenu1();
            break;
          case SUBMENU2:
            mMenu = new FragmentSubmenu2();
            break;
        }

        getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.menu_frame, mMenu)
        .commit();
      }

      @Override
      public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putSerializable(SUBMENU, curSubmenu);
        cloneCurrentSubmenuState(mMenu.getMenuData().
          getParcelable(MenuFragment.RESTORE_MAIN_OBJECT));
        outState.putParcelableArray(CONTAINER, menuData);

        // (...) stuff
      }

      @Override
      public void cloneCurrentSubmenuState(Parcelable toOverwrite) {
        if (menuData == null) menuData = new Bundle[Submenus.size()];

        if (toOverwrite != null) 
          mMenu.getMenuData().putParcelable(MenuFragment.RESTORE_MAIN_OBJECT, toOverwrite);

          menuData[Submenus.getId(curSubmenu)] = mMenu.cloneMenuData();
      }

      @Override
      public Bundle getLastStoredSubmenuState(Submenus forThisSubmenu) {
        return
          (menuData == null || !restoreLastSavedState) ? new Bundle() : menuData[Submenus.getId(forThisSubmenu)];
      }

      @Override
      public void setCurrentSubmenuTo(Submenus toThisSubmenu) {
        if (mMenu != null) {
          cloneCurrentSubmenuState(mMenu.getMenuData().
            getParcelable(MenuFragment.RESTORE_MAIN_OBJECT));
        }
        curSubmenu = toThisSubmenu;
        buildMenuFragment(true);
      }

子菜单之一(第 2 项的扩展):

    public class FragmentSubmenu1 extends MenuFragment {
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_submenu1, null);
      }

      @Override
      public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        init();
      }

      public void init() {
        // (...) stuff

        MyParcelableObject tmp = null; // MyParcelableObject is a class 
                                       // that implements Parcelable and stores 
                                       // relevant info to rebuild this menu 
                                       // from a saved state
        SubmenusManager m = (SubmenusManager) getActivity(); // remember activity implements SubmenusManager
        Bundle bnd = m.getLastStoredSubmenuState(SubmenusManager.Submenus.SUBMENU1);
        if (bnd != null) tmp = bnd.getParcelable(MenuFragment.RESTORE_MAIN_OBJECT);
        if (tmp == null) {
          tmp = new MyParcelableObject();
          tmp.buildFromScratch(); // initializes with default data
        }

        // back button
        Button backToMainMenu = (Button) getView().findViewById(R.id.submenu1_back);
        backToMainMenu.setOnClickListener(new OnClickListener() {
          @Override
          public void onClick(View v) {
            ((SubmenusManager) getActivity()).
              setCurrentSubmenuTo(SubmenusManager.Submenus.ROOTMENU);
          }
        });

        // (...) stuff
      }
    }

根菜单(项目 2 的扩展):

    public class FragmentRootMenu extends MenuFragment {
      View myView;

      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        myView = inflater.inflate(R.layout.fragment_rootmenu, null);
        return myView;
      }

      @Override
      public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        init();
      }

      public void init() {
        Button btnSubmenu1 = (Button) myView.findViewById(R.id.btn_call_submenu1);

        btnSubmenu1.setOnClickListener(new OnClickListener() {
          @Override
          public void onClick(View v) {
            ((SubmenusManager) getActivity()).
              setCurrentSubmenuTo(SubmenusManager.Submenus.SUBMENU1);
          }
        });

        Button btnSubmenu2 = (Button) myView.findViewById(R.id.btn_call_submenu2);

        btnSubmenu2.setOnClickListener(new OnClickListener() {
          @Override
          public void onClick(View v) {
            ((SubmenusManager) getActivity()).
              setCurrentSubmenuTo(SubmenusManager.Submenus.SUBMENU2);
          }
        });
      }
    }

为了在活动之间工作,您需要做的就是将存储所有片段的最后状态(在我的情况下是Bundle [] menuData)的对象传递给通过其调用的活动Intent;你会像我ExampleAct在它的onCreate(). 如果使用数组有问题,您还可以将其包装Bundle []在自定义 Parcelable 对象中(与我的示例非常相似MyParcelableObject;在那个里面我有类似的东西)。HashMap

这里如何在 Activity 之间传递 Parcelable: 如何使用 Intents 将对象从一个 Android Activity 发送到另一个?

于 2014-05-28T14:32:19.707 回答