1

Well, I'm trying to create a TabHostFragment inside a Fragment, the problem that I'm facing is that I can't implement it because I'm using already a drawer navigation. I was looking for some answers here in SO, but I didn't find the best way to do it. I'm using this Navigation drawer example, but I've added more fragments and more items, the thing is that I tried to implement this code of this example, but it doesn't work. I know it can be possible because Google Play, YouTube, Play Music... all of those app have a drawer navigation with Tabs inside.

The problem is that one of the all things I've tried is create a TabHostFragment adapter like in the example of the answer and then at the time to do this :

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;

I don't know if it's the correct way to do this but I tried, this case it's where it controls what item of the navigation drawer is clicked, then when the user clicks on the first item it should show the TabHost.

LogCat error looks like :

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

The line where is pointed this error is :

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

and in displayView(0):

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

I know this is not the best idea to go the FragmentTabHost (implement this on the switch case), but I tried also creating a new class like the exmaple of the answer and cann on this case fragment = new ClassWithTabs and it give to me the same error.

Please tell me what I'm missunderstanding or doing wrong, because I don't get what I'm doing wrong.

If you guys need more code you can ask to me and I'll post it as fast as I can.

EDIT

I've changed the import, I had import android.app.FragmentManager; and I changed to import android.support.v4.app.FragmentManager;, and only is giving me one error that is in this bunch of code :

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



    }

This is the error

enter image description here

This is the 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)
Community
  • 1
  • 1
Skizo-ozᴉʞS ツ
  • 19,464
  • 18
  • 81
  • 148

1 Answers1

2

You have forgotten to call

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

Add the above in your displayView() method immediately after calling findViewById().

EDIT:

1. Extend your MainActivity from FragmentActivity and not from Activity.

2. Make sure your FragmentManager is imported as

import android.support.v4.app.FragmentManager;

and not as

import android.app.FragmentManager;

EDIT 2:

Make sure your Fragment is imported as

import android.support.v4.app.Fragment;

and not as

import android.app.Fragment;

EDIT 3:

Your displayView() method should be:

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");
            }
        }
        }
    }
Yash Sampat
  • 30,051
  • 12
  • 94
  • 120