2016-09-06 166 views
0

最近我的工作我的应用程序,使其加载速度更快,工作得更好,我使用的导航抽屉里我的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到片段类,它需要4-5秒加载。因此,如果用户每次进入nav_camara时都在菜单之间导航,则会使应用程序停留4秒,并且每次我们选择菜单项时都会重新创建片段的副本,因此即使我制作:setRetainInstance(true);在我的片段类中它不会工作。

您建议什么解决方案,以防止应用程序每次我们选择一个菜单项时重新创建一个新的片段?

+0

也许加载是问题?而不是片段本身?尝试实现一些预取并在早些时候执行LoadJson任务。 – Christopher

+0

嘿刚刚访问[此链接](http://stackoverflow.com/questions/14839152/fragment-as-a-singleton-in-android)。希望在这里你可以找到有用的东西。 –

+0

我不认为它有什么区别,因为有一些计算,使culester标记和迭代json文件,并将其放在地图上,这需要很长时间,每次应用程序做一个片段的新副本这些计算将发生它认为该解决方案可能无法获得片段 – Blacksword

回答

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移动到您的MainFragmentonActivityCreated()或类似的生命周期方法中。

以上方式可以让你重用片段和移动逻辑到正确的位置(你的活动应该不知道怎么MainFragment数据加载到启动本身,当然你仍然可以保持它的存在,但不推荐)。

+0

here:fragmentTransaction.add(R.id.fragment_container,fragment); '片段'的价值是什么?我认为你忘了实例化它 – Blacksword

+0

@AryaR。固定的。 – Sufian

+0

我尝试这样的代码:int id = item.getItemId(); 如果(ID == R.id.nav_camara){ //设置片段最初 片段片段= myFragments.get(ID,新MainFragment()); //现在加载片段 FragmentTransaction fragmentTransaction = getSupportFragmentManager()。beginTransaction(); fragmentTransaction.add(R.id.fragment_container,fragment); fragmentTransaction.commit(); 它不工作:( – Blacksword

0

您可以在将新片段推送到容器时添加TAG。然后使用FragmentManager#findFragmentByTag查找以前添加了相同标记的任何片段。

 FragmentManager manager = getSupportFragmentManager(); 
     FragmentTransaction transaction = manager.beginTransaction(); 
     Fragment oldFragment = manager.findFragmentByTag(tag); 
     if (oldFragment != null) 
      transaction.replace(R.id.fragment_container, oldFragment, tag); 
     else 
      transaction.replace(R.id.fragment_container, newInstanceOfFragment, tag); 
     transaction.commit(); 
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; 
} 
+0

它没有任何区别 – Blacksword

+0

它有所不同。它不创建片段的另一个实例。至于jsonobject,请尝试将它作为参数传递,而不是传递给构造函数。不要在片段上创建构造函数。 –