2015-02-25 3 views
1

Ну, я пытаюсь создать TabHostFragment внутри Fragment, проблема, с которой я сталкиваюсь, заключается в том, что я не могу ее реализовать, потому что я использую уже навигацию на ящике. Я искал некоторые ответы здесь, в SO, но я не нашел лучшего способа сделать это. Я использую этот Navigation drawer example, но я добавил больше фрагментов и больше предметов, дело в том, что я пытался реализовать этот код этого example, но он не работает. Я знаю, что это возможно, потому что Google Play, YouTube, Play Music... все эти приложения имеют навигационную панель с вкладками внутри.
TabHost в фрагменте с NavigationDrawer

Проблема заключается в том, что одна из всех вещей, которые я пробовал, это создать адаптер TabHostFragment как в примере ответа, а затем в то время, чтобы сделать это:

private void displayView(int position) { 
    // update the main content by replacing fragments 
    Fragment fragment = null; 

    switch (position) { 
    case 0: 
     mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost); 


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

Я не» t знать, если это правильный способ сделать это, но я попытался, в этом случае он контролирует, какой элемент элемента навигации нажимается, а затем, когда пользователь нажимает на первый элемент, он должен показывать TabHost.

ошибка LogCat выглядит следующим образом:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.widget.TabHost$TabSpec android.support.v4.app.FragmentTabHost.newTabSpec(java.lang.String)' on a null object reference 

Линия, на которой указывается этой ошибки:

mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("Tab1"), 

и DisplayView (0):

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

Я знаю, что это не самая лучшая идея пойти FragmentTabHost (реализовать это в случае коммутатора), но я также попытался создать новый класс, например exmaple ответа и cann на этом случае fragment = new ClassWithTabs и он дает мне ту же ошибку.

Пожалуйста, расскажите мне, что я пропустил или не ошибаюсь, потому что я не понимаю, что я делаю неправильно.

Если вы, ребята, нуждаетесь в большем количестве кода, вы можете спросить меня, и я отправлю его как можно быстрее.

EDIT

Я изменил импорт, я имел import android.app.FragmentManager; и я изменил import android.support.v4.app.FragmentManager;, и только дает мне одну ошибку, которая находится в этой связке кода:

if (fragment != null) { 
      FragmentManager fragmentManager = getSupportFragmentManager(); 
      fragmentManager.beginTransaction() 
        .replace(R.id.frame_container, fragment).commit(); //here's the error 

      // update selected item and title, then close the drawer 
      mDrawerList.setItemChecked(position, true); 
      mDrawerList.setSelection(position); 
      setTitle(navMenuTitles[position]); 
      mDrawerLayout.closeDrawer(mDrawerList); 

Ошибка ->Error:(253, 37) error: incompatible types: android.app.Fragment cannot be converted to android.support.v4.app.Fragment

EDIT2

package info.androidhive.slidingmenu; 
import info.androidhive.slidingmenu.adapter.NavDrawerListAdapter; 
import info.androidhive.slidingmenu.model.NavDrawerItem; 
import java.util.ArrayList; 
import android.app.Fragment; 
import android.app.FragmentManager; 
import android.content.res.Configuration; 
import android.content.res.TypedArray; 
import android.graphics.drawable.ColorDrawable; 
import android.os.Bundle; 
import android.support.v4.app.ActionBarDrawerToggle; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.widget.DrawerLayout; 
import android.text.Html; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.ListView; 

    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; 

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


      // 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) { 
      //Fragment fragment = null; ---Removed for test, because if I don't remove this line couldn't execute the app because fragment can not call a FragmentActivity.... 
      FragmentActivity fragment = null; 

      switch (position) { 
       case 0: 
        fragment = new TabHostFragment(); 
        break; 

       default: 
       break; 


       if (fragment != null) { 
        FragmentManager fragmentManager = getFragmentManager(); 
        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); 
     } 



    } 

Это ошибка

enter image description here

Это TabHostFragment.class

package info.androidhive.slidingmenu; 

import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentTabHost; 

/** 
* Created by Joan on 26/02/2015. 
*/ 
public class TabHostFragment extends FragmentActivity { 
    // Fragment TabHost as mTabHost 
    private FragmentTabHost mTabHost; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 
     setContentView(R.layout.tabhost); 

     mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost); 
     mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent); 

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

    } 
} 

EDIT3

private void displayView(int position) { 
    //Fragment fragment = null; ---Removed for test, because if I don't remove this line couldn't execute the app because fragment can not call a FragmentActivity.... 

    if(position == 0){ 

     mDrawerList.setItemChecked(position, true); 
     mDrawerList.setSelection(position); 
     setTitle(navMenuTitles[position]); 
     mDrawerLayout.closeDrawer(mDrawerList); 
     setContentView(R.layout.tabhost); 

     mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost); 
     mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent); 

     mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("Mis ofertas"), 
       MisOfertasFragment.class, null); 
     mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("Recomendaciones"), 
       RecomendacionesFragment.class, null); 
    } 
    else 
    { 
     Fragment fragment = null; 

     switch (position) { 
      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"); 
     } 
    } 
} 

EDIT4 LogCatError

Process: info.androidhive.slidingmenu, PID: 2495 
java.lang.RuntimeException: Unable to start activity ComponentInfo{info.androidhive.slidingmenu/info.androidhive.slidingmenu.MainActivity}: android.content.ActivityNotFoundException: Unable to find explicit activity class {info.androidhive.slidingmenu/info.androidhive.slidingmenu.TabHostFragment}; have you declared this activity in your AndroidManifest.xml? 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360) 
    at android.app.ActivityThread.access$800(ActivityThread.java:144) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    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) 
Caused by: android.content.ActivityNotFoundException: Unable to find explicit activity class {info.androidhive.slidingmenu/info.androidhive.slidingmenu.TabHostFragment}; have you declared this activity in your AndroidManifest.xml? 
    at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1761) 
    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1485) 
    at android.app.Activity.startActivityForResult(Activity.java:3736) 
    at android.app.Activity.startActivityForResult(Activity.java:3697) 
    at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:817) 
    at android.app.Activity.startActivity(Activity.java:4007) 
    at android.app.Activity.startActivity(Activity.java:3975) 
    at info.androidhive.slidingmenu.MainActivity.displayView(MainActivity.java:221) 
    at info.androidhive.slidingmenu.MainActivity.onCreate(MainActivity.java:138) 
    at android.app.Activity.performCreate(Activity.java:5933) 
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360) 
    at android.app.ActivityThread.access$800(ActivityThread.java:144) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    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) 
+0

является 'DisplayView()' метод внутри 'Fragment'? –

+0

Этот displayView находится внутри моей MainActivity, что это Activity. –

+0

из того, что, кажется, вы пытаетесь это сделать 'android.widget.TabHost mTabHost = (android.support.v4.app.FragmentTabHost) findViewById (android.R.id.tabhost);' вы приписываете ему неправильный путь –

ответ

2

Вы забыли позвонить

mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent); 

Добавьте выше в методе displayView() сразу после вызова findViewById().

EDIT:

1. Расширьте MainActivity от FragmentActivity, а не от Activity.

2. Убедитесь, что ваш FragmentManager импортируется как

import android.support.v4.app.FragmentManager; 

, а не как

import android.app.FragmentManager; 

EDIT 2:

Убедитесь, что ваш Fragment импортируется как

import android.support.v4.app.Fragment; 

, а не как

import android.app.Fragment; 

РЕДАКТИРОВАТЬ 3:

Ваш метод displayView() должен быть:

private void displayView(int position) { 
     //Fragment fragment = null; ---Removed for test, because if I don't remove this line couldn't execute the app because fragment can not call a FragmentActivity.... 

    if(position == 0){ 

     mDrawerList.setItemChecked(position, true); 
     mDrawerList.setSelection(position); 
     setTitle(navMenuTitles[position]); 
     mDrawerLayout.closeDrawer(mDrawerList); 
     Intent intent = new Intent(MainActivity.this, TabHostFragment.class); 
     startActivity(intent); 
    } 
    else 
    { 
     Fragment fragment = null; 

     switch (position) { 
     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 = getFragmentManager(); 
       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"); 
      } 
     } 
     } 
    } 
+0

Можете ли вы попытаться помочь мне в этой же проблеме, пожалуйста, я не могу найти то, что я делаю неправильно :([link] (http://stackoverflow.com/questions/28836391/not-displaying-navigation-drawer-with-tabhostfragment) –

+0

Я посмотрю на это после некоторых время .... напомните, если я забуду :) –

+0

Помните: P –

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