防止重新创建导航抽屉片段

时间:2016-09-06 09:12:57

标签: android android-fragments android-navigation-drawer

最近,我正在使用我的应用程序来加快加载速度并提高工作效率,我在MainActivity中使用导航抽屉:

    @Override
public boolean onNavigationItemSelected(MenuItem item) {

    // Handle navigation view item clicks here.
    int id = item.getItemId();

    if (id == R.id.nav_camara) {
        LoadJson asyncTask = (LoadJson) new LoadJson(new LoadJson.AsyncResponse() {
            @Override
            public void processFinish(JSONArray output) {
                //Here you will receive the result fired from async class
                //of onPostExecute(result) method.
                //Set the fragment initially
                MainFragment fragment = new MainFragment(output);
                FragmentTransaction fragmentTransaction =
                        getSupportFragmentManager().beginTransaction();
                fragmentTransaction.add(R.id.fragment_container, fragment);
                fragmentTransaction.commit();
                // Handle the camera action
            }
        }).execute();


    } else if (id == R.id.nav_gallery) {
        //Set the fragment initially
        GalleryFragment fragment = new GalleryFragment();
        FragmentTransaction fragmentTransaction =
                getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.fragment_container, fragment);
        fragmentTransaction.commit();


    } else if (id == R.id.nav_search) {
        //Set the fragment initially
        FetchResualt fragment = new FetchResualt();
        FragmentTransaction fragmentTransaction =
                getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.fragment_container, fragment);
        fragmentTransaction.commit();
        // Handle the camera action

    } else if (id == R.id.nav_manage) {//
         Bundle bundle = new Bundle();//
        bundle.putInt("someStr",ID_OF_BEACH);//
        //Set the fragment initially//
        FragmentBeach fragment = new FragmentBeach();//
        fragment.setArguments(bundle);//
        FragmentTransaction fragmentTransaction =//
                getSupportFragmentManager().beginTransaction();//
        fragmentTransaction.replace(R.id.fragment_container, fragment);//
        fragmentTransaction.commit();//
        // Handle the camera action

    } else if (id == R.id.nav_share) {

    } else if (id == R.id.nav_send) {

    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

正如您所看到的,如果我们按下第一个菜单if (id == R.id.nav_camara),它会将JSONArray传递给Fragment类,并且需要4-5秒才能加载。因此,如果用户每次进入nav_camara时在菜单之间导航,它会使应用程序冻结加载4秒钟,您可以看到每次我们选择菜单项时,它将重新创建片段的新副本,因此即使我在我的片段类中做了setRetainInstance(true);它不会工作。

您建议在每次选择菜单项时阻止应用重新创建新片段的解决方案是什么?

3 个答案:

答案 0 :(得分:1)

您需要保留SparseArray<Fragment>以将实例保留在内存中。

请按照以下步骤操作:

  1. 在您的活动中创建一个字段:

    SparseArray<Fragment> myFragments;
    
  2. onCreate()中初始化它:

    myFragments = new SparseArray<Fragment>();
    
  3. 更新您的onNavigationItemSelected()

    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();
    
        if (id == R.id.nav_camara) {
            // get cached instance of the fragment
            fragment = myFragments.get(INT_CONSTANT_FOR_CAM_FRAGMENT);
    
            // if fragment doesn't exist in myFragments, create one and add to it
            if (fragment == null) {
                fragment = new MainFragment();
                myFragments.put(INT_CONSTANT_FOR_CAM_FRAGMENT, fragment);
            }
    
            // now load the fragment
            FragmentTransaction fragmentTransaction =
                        getSupportFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.fragment_container, fragment);
            fragmentTransaction.commit();
    
        }
        // do the rest with others as well.
    }
    
  4. 移动AsyncTask MainFragment onActivityCreated()内的MainFragment内容或类似的生命周期方法。
  5. 以上方式将让您重复使用片段并将逻辑移动到正确的位置(您的活动不应该知道 NoDemande NoUsager Sens IdVehiculeUtilise Fait HeureArriveeSurSite HeureEffective Periods 0 42196000013 000001 + 287Véh 1 11/07/2015 08:02:07 11/07/2015 08:02:13 Matin 1 42196000013 000001 - 287Véh 1 11/07/2015 08:17:09 11/07/2015 08:17:13 Matin 2 42196000002 000314 + 263Véh 1 11/07/2015 09:37:43 11/07/2015 09:53:37 Matin 3 42196000016 002372 + 287Véh 1 11/07/2015 09:46:42 11/07/2015 10:01:39 Matin 4 42196000015 000466 + 287Véh 1 11/07/2015 09:46:42 11/07/2015 10:01:39 Matin 5 42196000002 000314 - 263Véh 1 11/07/2015 10:25:17 11/07/2015 10:38:11 Matin 6 42196000015 000466 - 287Véh 1 11/07/2015 10:48:51 11/07/2015 10:51:30 Matin 7 42196000016 002372 - 287Véh 1 11/07/2015 11:40:56 11/07/2015 11:41:01 Matin 8 42196000004 002641 + 263Véh 1 11/07/2015 13:39:29 11/07/2015 13:52:50 Soir 9 42196000004 002641 - 263Véh 1 11/07/2015 13:59:56 11/07/2015 14:07:41 Soir 如何加载数据以启动自身,但当然您仍然可以将其保留在那里,虽然不推荐)。

答案 1 :(得分:0)

您可以在将新片段推送到容器时添加 File "/Users/name/projects/project_name/applications/views.py", line 462, in application_management form_kwargs={'request': request, 'application': application}) TypeError: modelformset_factory() got an unexpected keyword argument 'form_kwargs' 。然后使用Daniel查找以前添加了相同标记的任何片段。

TAG

答案 2 :(得分:0)

全球宣告

GalleryFragment galleryFrag = new GalleryFragment();
FragmentTransaction ft;
FragmentManager fm;

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...

    fm = getSupportFragmentManager();

    ...
}

然后选择导航

@Override
public boolean onNavigationItemSelected(MenuItem item) {

// Handle navigation view item clicks here.
int id = item.getItemId();

if (id == R.id.nav_search) {
    ft = fm.beginTransaction();
    ft.replace(R.id.fragment_container, galleryFrag).commit();
} 

DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}