17

Несколько дней назад я не реализован TabHostFramgent в Fragment с NavigationDrawer, и я столкнулся с проблемой, которая является следующее сообщение об ошибке:FragmentTabHost - Нет вкладки известно для тега нулевой

java.lang.IllegalStateException: Нет вкладки известный тег нулевого

Дела в том, что все работает отлично, так как мой первый список пункта из моих NavigationDrawer это мой TabHostFragment, поэтому он отлично работает, но проблема в том, когда я иду в примере ко второму пункту, а затем я хотите вернуться к первому элементу, каждый т ime, что я стараюсь, чтобы он сработал.

Я искал везде, здесь, в SO, code.google.com и т. Д., И я до сих пор не получил правильного ответа.

Мои tab_host_test_2.xml выглядит следующим образом:

<android.support.v4.app.FragmentTabHost xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@android:id/tabhost" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical" > 

     <TabWidget 
      android:id="@android:id/tabs" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:orientation="horizontal" /> 

     <FrameLayout 
      android:id="@android:id/tabcontent" 
      android:layout_width="0dp" 
      android:layout_height="0dp" 
      android:layout_weight="0" /> 

     <FrameLayout 
      android:id="@+id/realtabcontent" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_weight="1" /> 
    </LinearLayout> 

</android.support.v4.app.FragmentTabHost> 

Мои activity_main.xml где я получил мой NavigationDrawer выглядит следующим образом:

<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/drawer_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <!-- Framelayout to display Fragments --> 
    <FrameLayout 
     android:id="@+id/frame_container" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 


    <!-- Listview to display slider menu --> 
    <ListView 
     android:id="@+id/list_slidermenu" 
     android:layout_width="240dp" 
     android:layout_height="match_parent" 
     android:layout_gravity="start" 
     android:choiceMode="singleChoice" 
     android:divider="@color/list_divider" 
     android:dividerHeight="1dp" 
     android:listSelector="@drawable/list_selector" 
     android:background="@color/list_background"/> 
</android.support.v4.widget.DrawerLayout> 

Мои TabHostFragment.java:

public class TabHostFragment extends Fragment { 

    public TabHostFragment(){ 

    } 
    private FragmentTabHost mTabHost; 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.tab_host_test2, container, false); 
     return rootView; 
    } 

    @Override 
    public void onViewCreated(View view, Bundle savedInstanceState) { 
     mTabHost = (FragmentTabHost)view.findViewById(android.R.id.tabhost); 
     mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent); 

     mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("Tab1"), 
       MisOfertasFragment.class, null); 
     mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("Tab2"), 
       RecomendacionesFragment.class, null); 




    } 

} 

ActivityMain.java Мои:

public class MainActivity extends FragmentActivity { 
    private DrawerLayout mDrawerLayout; 
    private ListView mDrawerList; 
    private ActionBarDrawerToggle mDrawerToggle; 
    // saber si esta abierto 
    public boolean mDrawerOpened; 
    // nav drawer title 
    private CharSequence mDrawerTitle; 
    private FragmentTabHost mTabHost; 
    // used to store app title 
    private CharSequence mTitle; 

    //para ponerlo visible 
    public MenuItem mi; 

    // slide menu items 
    private String[] navMenuTitles; 
    private TypedArray navMenuIcons; 

    private ArrayList<NavDrawerItem> navDrawerItems; 
    private NavDrawerListAdapter adapter; 

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


     mTitle = mDrawerTitle = getTitle(); 

     // load slide menu items 
     navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items); 

     // nav drawer icons from resources 
     navMenuIcons = getResources() 
       .obtainTypedArray(R.array.nav_drawer_icons); 

     mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 
     mDrawerList = (ListView) findViewById(R.id.list_slidermenu); 

     navDrawerItems = new ArrayList<NavDrawerItem>(); 

     // adding nav drawer items to array 
     // Home 
     navDrawerItems.add(new NavDrawerItem(navMenuTitles[0], navMenuIcons.getResourceId(0, -1))); 
     // Find People 
     navDrawerItems.add(new NavDrawerItem(navMenuTitles[1], navMenuIcons.getResourceId(1, -1))); 
     // Photos 
     navDrawerItems.add(new NavDrawerItem(navMenuTitles[2], navMenuIcons.getResourceId(2, -1))); 
     // Communities, Will add a counter here 
     navDrawerItems.add(new NavDrawerItem(navMenuTitles[3], navMenuIcons.getResourceId(3, -1))); 
     // Pages 
     navDrawerItems.add(new NavDrawerItem(navMenuTitles[4], navMenuIcons.getResourceId(4, -1))); 
     // What's hot, We will add a counter here 
     navDrawerItems.add(new NavDrawerItem(navMenuTitles[5], navMenuIcons.getResourceId(5, -1))); 
     //AyudaSugerencias 
     navDrawerItems.add(new NavDrawerItem(navMenuTitles[6], navMenuIcons.getResourceId(6, -1))); 
     navDrawerItems.add(new NavDrawerItem(navMenuTitles[7], navMenuIcons.getResourceId(7, -1))); 


     // Recycle the typed array 
     navMenuIcons.recycle(); 

     mDrawerList.setOnItemClickListener(new SlideMenuClickListener()); 

     // setting the nav drawer list adapter 
     adapter = new NavDrawerListAdapter(getApplicationContext(), 
       navDrawerItems); 
     mDrawerList.setAdapter(adapter); 

     // enabling action bar app icon and behaving it as toggle button 

     getActionBar().setDisplayHomeAsUpEnabled(true); 
     getActionBar().setBackgroundDrawable(new ColorDrawable(0xff1d97dd)); 
     getActionBar().setHomeButtonEnabled(true); 

     mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, 
       R.drawable.ic_drawer, //nav menu toggle icon 
       R.string.app_name, // nav drawer open - description for accessibility 
       R.string.app_name // nav drawer close - description for accessibility 
     ) { 
      public void onDrawerClosed(View view) { 
       getActionBar().setTitle(
         Html.fromHtml("<font color='ffffff'>" 
           + mTitle + "</font>")); 

       // calling onPrepareOptionsMenu() to show action bar icons 
       invalidateOptionsMenu(); 
       mDrawerOpened = false; 
       syncState(); 

      } 

      public void onDrawerOpened(View drawerView) { 
       getActionBar().setTitle(
         Html.fromHtml("<font color='ffffff'>" 
           + mDrawerTitle + "</font>")); 

       // calling onPrepareOptionsMenu() to hide action bar icons 
       invalidateOptionsMenu(); 
       mDrawerOpened = true; 
       syncState(); 
      } 
     }; 
     mDrawerLayout.setDrawerListener(mDrawerToggle); 

     if (savedInstanceState == null) { 
      // on first time display view for first nav item 
      displayView(0); 
     } 
    } 

    /** 
    * Slide menu item click listener 
    */ 
    private class SlideMenuClickListener implements 
      ListView.OnItemClickListener { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, 
           long id) { 
      // display view for selected nav drawer item 
      displayView(position); 
     } 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 


     getMenuInflater().inflate(R.menu.main, menu); 


     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     Fragment fragment = null; 
     // toggle nav drawer on selecting action bar app icon/title 
     if (mDrawerToggle.onOptionsItemSelected(item)) { 
      return true; 
     } 
     // Handle action bar actions click 
     switch (item.getItemId()) { 
      case R.id.action_settings: 
       return true; 
      case R.id.ofertasRefresh: 
       return true; 
      case R.id.menu_search: 
       return true; 
      case R.id.newOffer: 
       getFragmentManager().beginTransaction().replace(R.id.frame_container, new TipusNouProducte()).commit(); 
       return true; 
      default: 
       return super.onOptionsItemSelected(item); 
     } 
    } 

    /* * 
    * Called when invalidateOptionsMenu() is triggered 
    */ 
    @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); 
     if (mDrawerOpened) { 
      menu.removeItem(R.id.ofertasRefresh); 
      menu.removeItem(R.id.menu_search); 
      menu.removeItem(R.id.newOffer); 
     } 
     if (!mDrawerOpened) { 
      menu.add(Menu.NONE, R.id.ofertasRefresh, Menu.NONE, mTitle); 
     } 
     return super.onPrepareOptionsMenu(menu); 

    } 

    /** 
    * Diplaying fragment view for selected nav drawer list item 
    */ 
    private void displayView(int position) { 
     mDrawerList.setItemChecked(position, true); 
     mDrawerList.setSelection(position); 
     setTitle(navMenuTitles[position]); 
     mDrawerLayout.closeDrawer(mDrawerList); 
     Fragment fragment = null; 

     switch (position) { 
      case 0: 
       fragment = new TabHostFragment(); 
       break; 
      case 1: 
       fragment = new RecomendacionesFragment(); 
       break; 
      case 2: 
       fragment = new LocalizacionFragment(); 
       break; 
      case 3: 
       fragment = new ListaProductosFragment(); 
       break; 
      case 4: 
       fragment = new ConfiguracionFragment(); 
       break; 
      case 5: 
       fragment = new AyudaSugerenciasFragment(); 
       break; 
      case 6: 
       fragment = new AyudaSugerencias(); 
       break; 

      default: 

       break; 
     } 


     if (fragment != null) { 
      FragmentManager fragmentManager = getSupportFragmentManager(); 
      fragmentManager.beginTransaction() 
        .replace(R.id.frame_container, fragment).commit(); /// here says that replace android.app.Fragment in FragmentTransaction cannot be applied... 

      // 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"); 
     } 
    } 


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

    } 

    /** 
    * When using the ActionBarDrawerToggle, you must call it during 
    * onPostCreate() and onConfigurationChanged()... 
    */ 

    @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 toggls 
     mDrawerToggle.onConfigurationChanged(newConfig); 
    } 



} 

Полная LogCat ошибка:

03-04 16:53:05.708 2232-2232/info.androidhive.slidingmenu E/AndroidRuntime﹕ FATAL EXCEPTION: main 
Process: info.androidhive.slidingmenu, PID: 2232 
java.lang.IllegalStateException: No tab known for tag null 
     at android.support.v4.app.FragmentTabHost.doTabChanged(FragmentTabHost.java:330) 
     at android.support.v4.app.FragmentTabHost.onAttachedToWindow(FragmentTabHost.java:280) 
     at android.view.View.dispatchAttachedToWindow(View.java:13406) 
     at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2707) 
     at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2714) 
     at android.view.ViewGroup.addViewInner(ViewGroup.java:3919) 
     at android.view.ViewGroup.addView(ViewGroup.java:3733) 
     at android.view.ViewGroup.addView(ViewGroup.java:3678) 
     at android.view.ViewGroup.addView(ViewGroup.java:3654) 
     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:958) 
     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126) 
     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739) 
     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1489) 
     at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:454) 
     at android.os.Handler.handleCallback(Handler.java:739) 
     at android.os.Handler.dispatchMessage(Handler.java:95) 
     at android.os.Looper.loop(Looper.java:135) 
     at android.app.ActivityThread.main(ActivityThread.java:5221) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:372) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 

EDIT

Ответ @Y.S., был своего рода разные, о чем я просил, но это может быть решением, но это совсем не сработало, и NavigationDrawer находится под номером TabHostFragment и т. д. Я не хочу ничего менять с помощью своего макета.

ответ

12

Как ошибка предлагает

Java: нелегальное состояние исключение: нет вкладки известного тега нулевого

вы пытались инициализируете TabHost но TabHost was null.


Попробуйте код, который я использовал для инициализации TabHost и она отлично работает. Держите код в onCreateView(). Эта проблема возникает, когда вы пытаетесь установить FragmentTabHost в onViewCreated(), что называется слишком поздним. Попытайтесь установить его в onCreateView() и добавьте хотя бы одну вкладку перед возвратом вида Object.

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

    // Create FragmentTabHost 
    mTabHost = new FragmentTabHost(getActivity()); 
    // Locate fragment1.xml to create FragmentTabHost 
    mTabHost.setup(getActivity(), getChildFragmentManager(), R.layout.fragment1); 
    mTabHost.addTab(mTabHost.newTabSpec("groups").setIndicator("",getResources().getDrawable(R.drawable.tab_group_icon)),FragmentTab1.class, null); 
    mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator("",getResources().getDrawable(R.drawable.tab_user_icon)),FragmentTab2.class, null); 

    MainActivity.fabButton.setVisibility(View.VISIBLE); 
    return mTabHost; 
} 

изменения Layout к:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 

    <FrameLayout 
     android:layout_width="match_parent" 
     android:layout_height="0dip" 
     android:layout_weight="1" /> 

    <android.support.v4.app.FragmentTabHost 
     android:id="@android:id/tabhost" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" > 

     <FrameLayout 
      android:id="@android:id/tabcontent" 
      android:layout_width="0dp" 
      android:layout_height="0dp" 
      android:layout_weight="0" /> 

    </android.support.v4.app.FragmentTabHost> 

</LinearLayout> 

Надеется, что это помогает.

+3

хорошо описание. –

+0

Я делаю то, что вы говорите, если я прихожу к макету Tabs, вниз, у них слишком много отступов или я не знаю, что произошло, все работает хорошо, но что такое фрагмент1? У меня есть 'mTabHost.setup (getActivity(), getChildFragmentManager(), R.id.realtabcontent);' и если я скопирую вставку вашего макета, это не позволяет мне помещать realtabcontent .. –

2

Существует еще один способ отображения вкладок, которые можно использовать здесь.

Определение TabHostFragment как это:

public class TabHostFragment extends Fragment implements ActionBar.TabListener{ 

    public TabHostFragment(){ 

    } 

    AppSectionsPagerAdapter mAppSectionsPagerAdapter; 
    ViewPager mViewPager; 

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

    @Override 
    public void onViewCreated(View view, Bundle savedInstanceState){ 
     mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getChildFragmentManager()); 

     final ActionBar actionBar = ((FragmentActivity)getActivity()).getSupportActionBar(); 

     actionBar.setHomeButtonEnabled(false); 
     actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 

     mViewPager = (ViewPager) view.findViewById(R.id.pager); 
     mViewPager.setAdapter(mAppSectionsPagerAdapter); 
     mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { 

      @Override 
      public void onPageSelected(int position) { 
       actionBar.setSelectedNavigationItem(position); 
      } 
     }); 

     for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) { 
      actionBar.addTab(
       actionBar.newTab() 
         .setText(mAppSectionsPagerAdapter.getPageTitle(i)) 
         .setTabListener(this)); 
     } 
    } 

    @Override 
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { 
    } 

    @Override 
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { 
     mViewPager.setCurrentItem(tab.getPosition()); 
    } 

    @Override 
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { 
    } 

    public static class AppSectionsPagerAdapter extends FragmentPagerAdapter { 

     public AppSectionsPagerAdapter(FragmentManager fm) { 
      super(fm); 
     } 

     @Override 
     public Fragment getItem(int i) { 
      Fragment f = null; 
      switch (i) { 
       case 0: 
        f = new MisOfertasFragment(); 
        break; 

       case 1: 
        f = new RecomendacionesFragment(); 
        break; 
      } 

      return f; 
     } 

     @Override 
     public int getCount() { 
      return 2; 
     } 

     @Override 
     public CharSequence getPageTitle(int position) { 
      return getFragmentTitle(position); 
     } 

     private String getFragmentTitle(int position){ 
      if(position == 0) 
       return "Tab 1"; 
      else if(position == 1) 
       return "Tab 2"; 
      else 
       return ""; 
     } 
    } 
} 

Определение tab_host_test2.xml так:

<android.support.v4.view.ViewPager 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/pager" 
android:layout_width="match_parent" 
android:layout_height="match_parent" /> 

Остальной код остается неизменным.

Попробуйте это. Это должно сработать.

EDIT:

Добавьте к этому методу displayView():

if(position != 0) 
    getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); 
+0

Хм хорошо, теперь вкладки фиксированы, а моя кнопка для перемещения моего навигационного ящика идет только в том случае, если я делаю правдоподобие, это не так, как мне жаль ... В примере: если я перейду к строке 4 на моем навигационном ящике все еще есть вкладки, и я просто хочу показать вкладки на моем первом элементе –

+0

Я понимаю ... для этого есть способ ... позвольте мне отредактировать мой ответ :) –

+0

см. отредактированный ответ –

0

укажите в XML-файл, в котором вы используете этот TabHostFragment (полный путь, как com.my.TabHostFragment).как

<com.my.TabHostFragment 
     android:id="@+id/fragmentId" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     /> 
+0

Что значит мой пакет.TabHostFragment? –

+0

Просто пример. Вы должны указать TabHostFragment с именем пакета в XML-файле. –

+0

Не работает ... –

Смежные вопросы