简体   繁体   English

Android导航抽屉碎片状态

[英]Android Navigation Drawer Fragment State

I'm currently utilizing the Navigation Drawer for my Android APP. 我目前正在为我的Android APP使用导航抽屉。 In my first fragment, I've a fragment that loads data using Facebook's Graph API. 在我的第一个片段中,我有一个使用Facebook的Graph API加载数据的片段。 Thus, when my App is first loaded, it first goes to the first fragment. 因此,当我的App首次加载时,它首先转到第一个片段。

第一

Then, I use the Navigation Drawer to click on another Fragment and view it. 然后,我使用导航抽屉点击另一个片段并查看它。

第二片段

And then finally, I reuse the Navigation Drawer to proceed back to the first Fragment and view it. 最后,我重复使用导航抽屉返回第一个片段并查看它。

第一片段

My issue that I'm facing is, how do I proceed to utilize the Fragment that has been created once instead of re-creating it whenever the Navigation Drawer Item is selected. 我面临的问题是,如何选择导航抽屉项目,如何继续使用已创建的片段,而不是重新创建片段。 My code for the switching of the fragments are as shown below. 我切换片段的代码如下所示。

private void displayView(int position) {
    // update the main content by replacing fragments
    Fragment fragment = null;
    switch (position) {
    case 0:
        fragment = new SelectionFragment();
        break;
    case 1:
        fragment = new HomeFragment();
        break;
    case 2:
        fragment = new PhotosFragment();
        break;
    case 3:
        fragment = new CommunityFragment();
        break;
    case 4:
        fragment = new PagesFragment();
        break;
    case 5:
        fragment = new SplashFragment();
        break;
    default:
        break;
    }

    if (fragment != null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.frame_container, fragment).commit();

        // update selected item and title, then close the drawer
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        setTitle(navMenuTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    } else {
        // error in creating fragment
        Log.e("MainActivity", "Error in creating fragment");
    }
}

I noticed that there is indeed a "new" instance of the Fragment every time whenever the option is selected. 我注意到每次选择选项时,片段确实存在“新”实例。 How do I go about implementing the logic of creating the Fragment instance ONCE and reusing it, so that I do not have to continuously load the Fragment over and over again. 我如何实现创建片段实例ONCE并重用它的逻辑,这样我就不必一遍又一遍地连续加载片段。

To anyone who encounters the same issue with me,I've managed to find a solution. 对于遇到同样问题的人,我设法找到了解决方案。

In the container frame,I've to define specific fragment views that I'll be utilizing as shown below. 在容器框架中,我将定义我将使用的特定片段视图,如下所示。

具体片段

In each Fragment view,I've to "link" it with the actual Fragment itself as shown below via the "android:name" attribute.Do take note of the the path to the Fragment,example for in my case it's com.example.confesssionsrp.SelectionFragment . 在每个片段视图中,我将通过“android:name”属性将其与实际片段本身“链接”,如下所示。请注意片段的路径 ,例如在我的例子中它是com.example .confesssionsrp.SelectionFragment

<fragment
    android:id="@+id/selectionFragment"
    android:name="com.example.confessionsrp.SelectionFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

In the the MainActivity(or the Activity where we're viewing the fragments),create variables for each of the Fragments as shown below. 在MainActivity(或我们正在查看片段的Activity)中,为每个片段创建变量,如下所示。

变量

Following that,in the Oncreate of the MainActivity(or your specific Activity),initialize the various fragments as shown below. 然后,在MainActivity的Oncreate (或您的特定活动)中,初始化各种片段,如下所示。

在OnCreate

Proceed onto creating a new Method called " ShowFragment " as shown below. 继续创建一个名为“ ShowFragment ”的新方法,如下所示。

private void showFragment(int fragmentIndex, boolean addToBackStack) {
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction transaction = fm.beginTransaction();
    for (int i = 0; i < fragments.length; i++) {
        if (i == fragmentIndex) {
            transaction.show(fragments[i]);
            if (Session.getActiveSession().isClosed()) {
                mDrawerLayout
                        .setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
            }
        } else {
            transaction.hide(fragments[i]);
        }
    }
    if (addToBackStack) {
        transaction.addToBackStack(null);
    }
    transaction.commit();
}

From then on in the switching of the fragments,manually call upon the " ShowFragment " method with the selected Fragment as shown below. 从那时起,在切换片段时,使用所选片段手动调用“ ShowFragment ”方法,如下所示。

显示片段

Doing all of this overall,will not reset the Fragment each time we view it,and therefore is the solution to the answer.Thank you for anyone who has helped me so far :)! 完成所有这些操作,每次我们查看时都不会重置片段,因此是答案的解决方案。感谢迄今为止帮助过我的任何人:)!

I am using the following code: 我使用以下代码:

@Override
public void onNavigationDrawerItemSelected(int position) {

    // update the main content by replacing fragments
    FragmentManager fragmentManager = getFragmentManager();
    if(position==0){// selection of tabs content
        fragmentManager
        .beginTransaction()
        .replace(R.id.container,
                SimulatorFragment.newInstance(position + 1)).commit();
    }else if(position==1){
        fragmentManager
        .beginTransaction()
        .replace(R.id.container,
                HudFragment.newInstance(position + 1)).commit();
    }else if(position==2){
        // Display the fragment as the main content.
        fragmentManager
        .beginTransaction()
        .replace(R.id.container, 
                SettingsBasicFragment.newInstance(position +1)).commit();
    }else{

    }
}

You can replace by a new instance the first time and store the fragment, if it is not null, then replace by the stored fragment. 您可以第一次用新实例替换并存储片段,如果它不为null,则替换为存储的片段。

The activity must implement NavigationDrawerFragment.NavigationDrawerCallbacks 该活动必须实现NavigationDrawerFragment.NavigationDrawerCallbacks

The fragment constructor and newInstance methods look like this: 片段构造函数和newInstance方法如下所示:

public final class HudFragment extends Fragment {
/**
 * The fragment argument representing the section number for this
 * fragment.
 */
private static final String ARG_SECTION_NUMBER = "section_number";

/**
 * Returns a new instance of this fragment for the given section number.
 * @param simulation 
 */
public static HudFragment newInstance(int sectionNumber) {  
    HudFragment fragment = new HudFragment();
    Bundle args = new Bundle();
    args.putInt(ARG_SECTION_NUMBER, sectionNumber);
    fragment.setArguments(args);
    return fragment;
}

public HudFragment() {
}

To switch fragments by code I use this method inside the NavigationDrawerFragment: 要按代码切换片段,我在NavigationDrawerFragment中使用此方法:

/**
 * Select a different section
 * @param position
 */
public void select(int position){
    selectItem(position);
}

private void selectItem(int position) {
    mCurrentSelectedPosition = position;
    if (mDrawerListView != null) {
        mDrawerListView.setItemChecked(position, true);
    }            
    if (mDrawerLayout != null) {
        mDrawerLayout.closeDrawer(mFragmentContainerView);
    }
    if (mCallbacks != null) {
        mCallbacks.onNavigationDrawerItemSelected(position);
    }
}

The second option is to start with the example of navigationDrawer that Android SDK offers. 第二个选项是从Android SDK提供的navigationDrawer示例开始。 I selected that template of activity when creating the project and almost all the code of my previous answer is produced automatically. 我在创建项目时选择了该活动模板,几乎所有前一个答案的代码都是自动生成的。

If you want to keep the fragments after device rotation or similars it is a different thing, you need then to retain the fragments. 如果你想在设备旋转或类似物之后保留片段,那么你需要保留碎片。 If not, you just need to save the new instance of the fragment in a variable and check if it is null to create a new one or use the old one. 如果没有,您只需要在变量中保存片段的新实例,并检查它是否为null以创建新的或使用旧的。

In case someone want's a different approach to this: you could find the fragment on the stack: 如果有人想要一个不同的方法:你可以在堆栈上找到片段:

// check if this fragment is on the backstack to avoid creating a new one
    Fragment foundFragment =  fragmentManager.findFragmentByTag("unique_fragment_tag");
    if (foundFragment != null) {
          fragmentManager.popBackStackImmediate("unique_fragment_tag", 0);
            return;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM