2014-03-03 7 views
23

Ich habe eine MainDrawer zu Fragment Aktivität, die ein Layout für eine Nav Schublade hat und mein Hauptinhalt, wo ich neue Fragmente laden kann. Ein Fragment, das ich einlade, ist calle StatisticsTab Fragment. Dieses Fragment enthält einen Tabhost, wobei jede Registerkarte ihr eigenes Fragment von Listenansichtselementen ist. Sobald ich auf einem Listview-Elemente klicken, das ein weiteres neues Fragment lädt und bin nicht mehr in der TabHost und ich versuche, die navigationdrawer mein StatisticsTab Fragment zurück zu gehen mit bekomme ich diesen Fehler:Rekursiver Eintrag zu executePendingTransactions

03-03 10:32:06.884 24185-24185/com.beerportfolio.beerportfoliopro E/AndroidRuntime﹕ FATAL EXCEPTION: main 
    java.lang.IllegalStateException: Recursive entry to executePendingTransactions 
      at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1439) 
      at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:472) 
      at android.support.v4.app.FragmentTabHost.onAttachedToWindow(FragmentTabHost.java:283) 
      at android.view.View.dispatchAttachedToWindow(View.java:12307) 
      at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2457) 
      at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2464) 
      at android.view.ViewGroup.addViewInner(ViewGroup.java:3567) 
      at android.view.ViewGroup.addView(ViewGroup.java:3399) 
      at android.view.ViewGroup.addView(ViewGroup.java:3344) 
      at android.view.ViewGroup.addView(ViewGroup.java:3320) 
      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:938) 
      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104) 
      at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) 
      at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467) 
      at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440) 
      at android.os.Handler.handleCallback(Handler.java:730) 
      at android.os.Handler.dispatchMessage(Handler.java:92) 
      at android.os.Looper.loop(Looper.java:158) 
      at android.app.ActivityThread.main(ActivityThread.java:5789) 
      at java.lang.reflect.Method.invokeNative(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:525) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:843) 
      at dalvik.system.NativeStart.main(Native Method) 

Wenn ich nicht klicken auf einem meiner Tabs, obwohl auf dem StatisticsTab-Fragment und navigieren Sie zu einem anderen Fragment über die Navdrawer und dann zurück zum StatisticsTab dann wird es nicht FC auf. Auch keines der anderen Fragmente in der NavDrawer-Kraft schließt sich, wenn ich zu ihnen zurückkehre, nur das mit den Tabs.

MainDrawer2:

public class MainDrawer2 extends FragmentActivity 
{ 
    private static final String EXTRA_NAV_ITEM = "extraNavItem"; 
    private static final String STATE_CURRENT_NAV = "stateCurrentNav"; 

    private ActionBarDrawerToggle mDrawerToggle; 
    private DrawerLayout mDrawerLayout; 

    private NavDrawerListAdapter mDrawerAdapter; 
    private ListView mDrawerList; 

    private CharSequence mTitle; 
    private CharSequence mDrawerTitle; 

    private MainNavItem mCurrentNavItem; 


    public static Intent createLaunchFragmentIntent(Context context, MainNavItem navItem) 
    { 
     return new Intent(context, MainDrawer2.class) 
       .putExtra(EXTRA_NAV_ITEM, navItem.ordinal()); 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.fragment_main); 

     mTitle = mDrawerTitle = getTitle(); 
     mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout); 
     mDrawerList = (ListView)findViewById(R.id.drawer); 

     getActionBar().setDisplayHomeAsUpEnabled(true); 
     enableHomeButtonIfRequired(); 

     mDrawerAdapter = new NavDrawerListAdapter(getApplicationContext()); 
     mDrawerList.setAdapter(mDrawerAdapter); 
     mDrawerList.setOnItemClickListener(new ListView.OnItemClickListener() 
     { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
      { 
       displayNavFragment((MainNavItem)parent.getItemAtPosition(position)); 
      } 
     }); 

     mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, 
       R.drawable.ic_drawer, R.string.app_name, R.string.app_name) 
     { 
      public void onDrawerClosed(View view) 
      { 
       getActionBar().setTitle(mTitle); 
       invalidateOptionsMenu(); 
      } 

      public void onDrawerOpened(View drawerView) 
      { 
       getActionBar().setTitle(mDrawerTitle); 
       invalidateOptionsMenu(); 
      } 
     }; 

     mDrawerLayout.setDrawerListener(mDrawerToggle); 

     if(getIntent().hasExtra(EXTRA_NAV_ITEM)){ 
      MainNavItem navItem = MainNavItem.values() 
        [getIntent().getIntExtra(EXTRA_NAV_ITEM, 
        MainNavItem.STATISTICS.ordinal())]; 
      displayNavFragment(navItem); 
     } 
     else if(savedInstanceState != null){ 
      mCurrentNavItem = MainNavItem.values() 
        [savedInstanceState.getInt(STATE_CURRENT_NAV)]; 
      setCurrentNavItem(mCurrentNavItem); 
     } 
     else{ 
      displayNavFragment(MainNavItem.STATISTICS); 
     } 
    } 

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 
    private void enableHomeButtonIfRequired() 
    { 
     if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){ 
      getActionBar().setHomeButtonEnabled(true); 
     } 
    } 

    @Override 
    public void setTitle(CharSequence title) 
    { 
     mTitle = title; 
     getActionBar().setTitle(mTitle); 
    } 

    @Override 
    protected void onPostCreate(Bundle savedInstanceState) 
    { 
     super.onPostCreate(savedInstanceState); 
     // Sync the toggle state after onRestoreInstanceState has occurred. 
     mDrawerToggle.syncState(); 
    } 

    @Override 
    public void onConfigurationChanged(Configuration newConfig) 
    { 
     super.onConfigurationChanged(newConfig); 
     // Pass any configuration change to the drawer toggles 
     mDrawerToggle.onConfigurationChanged(newConfig); 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) 
    { 
     super.onSaveInstanceState(outState); 
     outState.putInt(STATE_CURRENT_NAV, mCurrentNavItem.ordinal()); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) 
    { 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

    /* 
    @Override 
    public boolean onPrepareOptionsMenu(Menu menu) 
    { 
     // if nav drawer is opened, hide the action items 
     boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList); 
     menu.findItem(R.id.action_settings).setVisible(!drawerOpen); 
     return super.onPrepareOptionsMenu(menu); 
    } 
    */ 



    private void displayNavFragment(MainNavItem navItem) 
    { 
     if(navItem == mCurrentNavItem){ 
      return; 
     } 
     Fragment fragment = Fragment.instantiate(this, 
       navItem.getFragClass().getName()); 
     if(fragment != null){ 

      getSupportFragmentManager().beginTransaction() 
        .replace(R.id.main, fragment) 
        .commit(); 
      setCurrentNavItem(navItem); 
     } 
    } 

    private void setCurrentNavItem(MainNavItem navItem) 
    { 
     int position = navItem.ordinal(); 
     // If navItem is in DrawerAdapter 
     if(position >= 0 && position < mDrawerAdapter.getCount()){ 
      mDrawerList.setItemChecked(position, true); 
     } 
     else{ 
      // navItem not in DrawerAdapter, de-select current item 
      if(mCurrentNavItem != null){ 
       mDrawerList.setItemChecked(mCurrentNavItem.ordinal(), false); 
      } 
     } 
     mDrawerLayout.closeDrawer(mDrawerList); 
     setTitle(navItem.getTitleResId()); 
     mCurrentNavItem = navItem; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
      case android.R.id.home: 
       if(mDrawerLayout.isDrawerOpen(mDrawerList)) { 
        mDrawerLayout.closeDrawer(mDrawerList); 
       } 
       else { 
        mDrawerLayout.openDrawer(mDrawerList); 
       } 
       return true; 
      default: 
       return super.onOptionsItemSelected(item); 
     } 
    } 




    public void goToSearch(MenuItem item){ 

     //go to search page 
     Fragment Fragment_one; 
     FragmentManager man= getSupportFragmentManager(); 
     FragmentTransaction tran = man.beginTransaction(); 
     Fragment_one = new Search(); 

     tran.replace(R.id.main, Fragment_one);//tran. 
     tran.addToBackStack(null); 
     tran.commit(); 

    } 



} 

StatisticsTab:

public class StatisticsTab extends Fragment { 


    private FragmentTabHost mTabHost; 

    //Mandatory Constructor 
    public StatisticsTab() { 
    } 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

    } 

    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 

     View rootView = inflater.inflate(R.layout.fragment_tabs,container, false); 


     mTabHost = (FragmentTabHost)rootView.findViewById(android.R.id.tabhost); 

     mTabHost.setup(getActivity(), getFragmentManager(), R.id.realtabcontent); 

     mTabHost.addTab(mTabHost.newTabSpec("Basic").setIndicator("Basic"), 
       StatisticsPage.class, null); 
     mTabHost.addTab(mTabHost.newTabSpec("Brewery").setIndicator("Brewery"), 
       BreweryStatistics.class, null); 
     mTabHost.addTab(mTabHost.newTabSpec("Style").setIndicator("Style"), 
       StyleStatistics.class, null); 
     mTabHost.addTab(mTabHost.newTabSpec("Taste").setIndicator("Taste"), 
       TasteStatisticsPage.class, null); 



     return rootView; 
    } 




} 

Einer meiner Fragmente für eine Registerkarte in der TabHost, die eine Listenansicht hat:

public class BreweryStatistics extends Fragment implements GetBreweryStatisticsJSON.OnArticleSelectedListener { 

    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View v = inflater.inflate(R.layout.brewery_statistics_layout, container, false); 

     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); 
     String userName = prefs.getString("userName", null); 
     String userID = prefs.getString("userID", null); 

     String url = "myURL"; 


     //async task to get beer taste tag percents 
     GetBreweryStatisticsJSON task = new GetBreweryStatisticsJSON(getActivity()); 
     task.setOnArticleSelectedListener(this); 
     task.execute(url); 


     // Inflate the layout for this fragment 
     return v; 

    } 


    @Override 
    public void onArticleSelected(String bID){ 

     //code to execute on click 
     Fragment Fragment_one; 
     FragmentManager man= getFragmentManager(); 
     FragmentTransaction tran = man.beginTransaction(); 
     Fragment_one = new BreweryPage2(); 
     final Bundle bundle = new Bundle(); 
     bundle.putString("breweryIDSent", bID); 
     Fragment_one.setArguments(bundle); 

     tran.replace(R.id.main, Fragment_one);//tran. 
     tran.addToBackStack(null); 
     tran.commit(); 

    } 


} 

Meine Async Aufgabe für die oben Fragment zum Laden der Listenansicht:

public class GetBreweryStatisticsJSON extends AsyncTask<String, Void, String> { 

    Context c; 
    private ProgressDialog Dialog; 


    public GetBreweryStatisticsJSON(Context context) 
    { 
     c = context; 
     Dialog = new ProgressDialog(c); 
    } 

    //***************************code for on click 
    OnArticleSelectedListener listener; 
    public interface OnArticleSelectedListener{ 
     public void onArticleSelected(String myString); 


    } 
    public void setOnArticleSelectedListener(OnArticleSelectedListener listener){ 
     this.listener = listener; 


    } 
    //*****************************end code for onClick 

    protected void onPreExecute() { 
     Dialog.setMessage("Analyzing breweries"); 

     Dialog.setTitle("Loading"); 
     Dialog.setCancelable(false); 
     Dialog.show(); 
    } 


    @Override 
    protected String doInBackground(String... arg0) { 
     // TODO Auto-generated method stub 
     return readJSONFeed(arg0[0]); 
    } 

    protected void onPostExecute(String result){ 
     //decode json here 
     try{ 
      JSONArray jsonArray = new JSONArray(result); 


      //acces listview 
      ListView lv = (ListView) ((Activity) c).findViewById(R.id.yourBreweryStatistics); 

      //make array list for beer 
      final List<BreweryInfo> tasteList = new ArrayList<BreweryInfo>(); 



      for(int i = 0; i < jsonArray.length(); i++) { 

       String brewery = jsonArray.getJSONObject(i).getString("brewery"); 
       String rate = jsonArray.getJSONObject(i).getString("rate"); 
       String breweryID = jsonArray.getJSONObject(i).getString("id"); 

       int count = i + 1; 

       brewery = count + ". " + brewery; 

       Log.d("brewery stats", brewery); 

       //create object 
       BreweryInfo tempTaste = new BreweryInfo(brewery, breweryID, rate); 

       //add to arraylist 
       tasteList.add(tempTaste); 


       //add items to listview 
       BreweryInfoAdapter adapter1 = new BreweryInfoAdapter(c ,R.layout.brewer_stats_listview, tasteList); 
       lv.setAdapter(adapter1); 

       //set up clicks 
       lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
        @Override 
        public void onItemClick(AdapterView<?> arg0, View arg1, 
              int arg2, long arg3) { 
         BreweryInfo o=(BreweryInfo)arg0.getItemAtPosition(arg2); 

         String bID = o.breweryID; 

         Log.d("breweryID" , bID); 

         //todo: add brewery page link 
         //********************* add listener 
         listener.onArticleSelected(bID); 


        } 
       }); 

      } 

     } 
     catch(Exception e){ 

     } 

     Dialog.dismiss(); 

    } 

    public String readJSONFeed(String URL) { 
     StringBuilder stringBuilder = new StringBuilder(); 
     HttpClient httpClient = new DefaultHttpClient(); 
     HttpGet httpGet = new HttpGet(URL); 
     try { 
      HttpResponse response = httpClient.execute(httpGet); 
      StatusLine statusLine = response.getStatusLine(); 
      int statusCode = statusLine.getStatusCode(); 
      if (statusCode == 200) { 
       HttpEntity entity = response.getEntity(); 
       InputStream inputStream = entity.getContent(); 
       BufferedReader reader = new BufferedReader(
         new InputStreamReader(inputStream)); 
       String line; 
       while ((line = reader.readLine()) != null) { 
        stringBuilder.append(line); 
       } 
       inputStream.close(); 
      } else { 
       Log.d("JSON", "Failed to download file"); 
      } 
     } catch (Exception e) { 
      Log.d("readJSONFeed", e.getLocalizedMessage()); 
     } 
     return stringBuilder.toString(); 
    } 



} 
+0

möglich Duplikat [ViewPager: rekursive Eintrag executePendingTransactions] (http://stackoverflow.com/questions/7338823/viewpager-recursive-entry-to-executependingtransactions) – rds

Antwort

55

Sie versuchen, Fragmente, die in anderen Fragmenten verschachtelt sind, über Ihren FragmentTabHost zu verwenden.

In Ihrem StatisticsTab Fragment, das ändern:

mTabHost.setup(getActivity(), getFragmentManager(), R.id.realtabcontent); 

dazu:

mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent); 


Dann stellen Sie sicher, dass die Eltern FragmentManager verwenden, um das Haupt-Fragment Änderung zu begehen, durch getFragmentManager() Wechsel zu getActivity().getSupportFragmentManager() innerhalb BreweryStatistics.onArticleSelected().


See:
ViewPager: Recursive entry to executePendingTransactions
Nested Fragments using support library v4 revision 11

+0

wo würde ich in getSupportFragmentManager() vs getChildFragmentManager() ändern? – Mike

+0

Entschuldigung, der Activity Code wurde falsch gelesen, Sie verwenden getSupportFragmentManager() korrekt in Ihrer Schublade. Siehe meine aktualisierte Antwort zur Klarstellung. –

+0

genial, aber das ist eigentlich, was ich ursprünglich hatte und ich bekomme einen seltsamen ID-Fehler, wenn ich versuche, eine Auswahl aus meiner ListView, die in der Registerkarte ist. Ich werde es schnell zurück ändern und Ihnen den Fehler zeigen. – Mike

Verwandte Themen