2015-06-18 11 views
11

mam TabHost Wewnątrz navigationDrawer i jestem w obliczu tego dziwnego problemu, który występuje, gdy kiedykolwiek pójdę z TabHost który istnieje jako element szuflady nawigacji do innego elementu szuflady nawigacji i wrócić do TabHost nie wyświetli swojej zawartości, za pierwszym razem działa idealnie, ale kiedy tylko zmienię przedmiot i wrócę do niego, nie wyświetli treści; innymi słowy, nie załaduje fragmentów potomnych, chyba że zamknę aplikację i ponownie ją uruchomię lub zmieni orientację (odtwórz fragment).TabHost wyświetla zawartości raz (onCreate)

Jak to wygląda po raz pierwszy otworzyć go (wraz z zawartością)

enter image description here

Po przejściu do innego navDrawer pozycję i powrócić do TabHost

enter image description here

TabHost Fragment:

import android.content.Context; 
import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentPagerAdapter; 
import android.support.v4.view.ViewPager; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TabHost; 
import android.widget.TabWidget; 

import java.util.ArrayList; 

import info.fds.Emirates.R; 

public class MyFragment extends Fragment 
{ 

    private TabHost mTabHost; 
    private ViewPager mViewPager; 
    private TabsAdapter mTabsAdapter; 

    public MyFragment() { 
    } 

    @Override 
    public void onCreate(Bundle instance) 
    { 
     super.onCreate(instance); 

    } 

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

     mTabHost = (TabHost) v.findViewById(android.R.id.tabhost); 
     mTabHost.setup(); 

     mViewPager = (ViewPager) v.findViewById(R.id.pager); 
     mTabsAdapter = new TabsAdapter(getActivity(), mTabHost, mViewPager); 



     return v; 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     // Here we load the content for each tab. 
     mTabsAdapter.addTab(mTabHost.newTabSpec("Incident").setIndicator("Incident"), PageOneFragment.class, null); 
     mTabsAdapter.addTab(mTabHost.newTabSpec("Service Request").setIndicator("Service Request"), PageTwoFragment.class, null); 
    } 

    public static class TabsAdapter extends FragmentPagerAdapter implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener 
    { 
     private final Context mContext; 
     private final TabHost mTabHost; 
     private final ViewPager mViewPager; 
     private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); 

     static final class TabInfo 
     { 
      private final String tag; 
      private final Class<?> clss; 
      private final Bundle args; 

      TabInfo(String _tag, Class<?> _class, Bundle _args) 
      { 
       tag = _tag; 
       clss = _class; 
       args = _args; 
      } 
     } 

     static class DummyTabFactory implements TabHost.TabContentFactory 
     { 
      private final Context mContext; 

      public DummyTabFactory(Context context) 
      { 
       mContext = context; 
      } 

      public View createTabContent(String tag) 
      { 
       View v = new View(mContext); 
       v.setMinimumWidth(0); 
       v.setMinimumHeight(0); 
       return v; 
      } 
     } 

     public TabsAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager) 
     { 
      super(activity.getSupportFragmentManager()); 
      mContext = activity; 
      mTabHost = tabHost; 
      mViewPager = pager; 
      mTabHost.setOnTabChangedListener(this); 
      mViewPager.setAdapter(this); 
      mViewPager.setOnPageChangeListener(this); 
     } 

     public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) 
     { 
      tabSpec.setContent(new DummyTabFactory(mContext)); 
      String tag = tabSpec.getTag(); 

      TabInfo info = new TabInfo(tag, clss, args); 
      mTabs.add(info); 
      mTabHost.addTab(tabSpec); 
      notifyDataSetChanged(); 
     } 

     @Override 
     public int getCount() 
     { 
      return mTabs.size(); 
     } 

     @Override 
     public Fragment getItem(int position) 
     { 
      TabInfo info = mTabs.get(position); 

      return Fragment.instantiate(mContext, info.clss.getName(), info.args); 

     } 

     public void onTabChanged(String tabId) 
     { 
      int position = mTabHost.getCurrentTab(); 
      mViewPager.setCurrentItem(position); 
     } 

     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) 
     { 
     } 

     public void onPageSelected(int position) 
     { 
      // Unfortunately when TabHost changes the current tab, it kindly 
      // also takes care of putting focus on it when not in touch mode. 
      // The jerk. 
      // This hack tries to prevent this from pulling focus out of our 
      // ViewPager. 
      TabWidget widget = mTabHost.getTabWidget(); 
      int oldFocusability = widget.getDescendantFocusability(); 
      widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); 
      mTabHost.setCurrentTab(position); 
      widget.setDescendantFocusability(oldFocusability); 
     } 

     public void onPageScrollStateChanged(int state) 
     { 
     } 
    } 
} 

PageOneFragment:

public class PageOneFragment extends Fragment 
{ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    { 
     return inflater.inflate(R.layout.pageone_fragment, container, false); 
    } 

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

    @Override 
    public void onAttach(Activity activity) 
    { 
     super.onAttach(activity); 
    } 

    @Override 
    public void onStart() 
    { 
     super.onStart(); 
    } 

    @Override 
    public void onResume() 
    { 
     super.onResume(); 
    } 
} 

PageTwoFragment

public class PageTwoFragment extends Fragment 
{ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    { 
     return inflater.inflate(R.layout.pagetwo_fragment, container, false); 
    } 

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

    @Override 
    public void onAttach(Activity activity) 
    { 
     super.onAttach(activity); 
    } 

    @Override 
    public void onStart() 
    { 
     super.onStart(); 
    } 

    @Override 
    public void onResume() 
    { 
     super.onResume(); 
    } 
} 

Uwaga: Po debugowania Zauważyłem, że onCreateView() w PageOneFragment i StronaTwoFragment nie jest wykonywany.

co się dzieje i dlaczego tabHost nie ładuje swojej zawartości po przejściu do innego elementu?

EDIT: Po godzinach bolesnej debugowania odkryłem, że mój kod nie wykona metodę odłogowania na drugim naborze, który jest:

@Override 
     public Fragment getItem(int position)//never get executed after the second call 
     { 
      TabInfo info = mTabs.get(position); 

      return Fragment.instantiate(mContext, info.clss.getName(), info.args); 

     } 

jak można rozwiązać ten problem?

każda pomoc jest naprawdę doceniana.

Z góry dziękuję.

+0

Witam. Nie publikuj całego kodu, tylko niezbędny do zrozumienia twojego problemu. Byłoby wspaniale, gdybyś mógł stworzyć skrzypce. – Cthulhu

+0

@Cululhu zrobione .. –

Odpowiedz

11

kosztował mnie ten śmieszny błąd dużo czasu, a rozwiązanie było rzeczywiście bardzo proste, jest to, że używałem FragmentPagerAdapter zamiast FragmentStatePagerAdapter po wymianie go, wszystko działa idealnie, mam nadzieję, że to pomoże innym z podobnym problemem .

+0

mi stanął dokładnie w tej samej sytuacji, zaledwie dwa dni temu! dla mnie też zajęło to dużo czasu !! dwa dni wcześniej tylko zorientowali się w tym rozwiązaniu na innym poście SO! Tak, to niedorzeczne! (i to było moje pytanie! http://stackoverflow.com/q/30885610/2811343) – AndroidManifester

1

w was kodzie FragmentPageAdapter będzie za pomocą aktywność na FragmentManager ale kiedy instantiateItem w FragmentPageAdapter, znajdzie fragment aktywności na FragmentManager. To niefortunne, PageOneFragment i PageTwoFragment nie będąc w działalność na FragmentManager, więc nie są nowe stworzenie PageOneFragment i PageTwoFragment The FragmentPageAdapter użyje PageOneFragment w backstack fragmentu.Ale PageOneFragment został dodany w ostatnim numerze FragmentPageAdapter, a następnie nie ma żadnych treści.

Korzystanie FragmentPageStateAdapter zastąpić FragmentPageAdapter jest prostym wyborem. Jeśli chcesz użyć FragmentPageAdapter, która jest lepsza niż FragmentPageStateAdapter w niektórych czasach, można go używać tak:

public TabsAdapter(Fragment fragment, TabHost tabHost, ViewPager pager) 
    { 
     super(fragment.getChildFragmentManager()); 


     mContext = fragment.getActivity(); 
     mTabHost = tabHost; 
     mViewPager = pager; 
     mTabHost.setOnTabChangedListener(this); 
     mViewPager.setAdapter(this); 
     mViewPager.setOnPageChangeListener(this); 
     Log.i("Test", "TabsAdapter super"); 
    } 

pomocą ChildFragmentManager.

Myślę, że jeśli usuniesz PageOneFragment i PageTwoFragment z zakresu aktywności FragmentManager, jest również w porządku.

Powiązane problemy