1

I have a Main Activity which uses a TabSelectedListener to show fragments for the AHBottomNavigation menu. The fragment called "FirstFragment" contains a FragmentPagerAdapter which allows the user to swipe between two tabs, each of which have its own fragment, called FirstTabInFirstFragmentFragment and SecondTabInFirstFragmentFragment (renamed for simplicity).

My issue is that:

a). When the Main Activity is launched, the "First" Bottom Navigation menu item is selected, however the "FirstFragment" is not launched. So, it shows the proper item selected with a blank screen. It only launches the First Fragment if I tap on the menu item again.

b). Once the FirstFragment has been properly launched and is being shown on screen (by the temporary fix done in a), if I select a different menu item (i.e. to navigate to SecondFragment) and then select the FirstFragment's menu item again, the two tabs within it are blank. Also, the sliding between the fragments for the two tabs does not work and gets "stuck" so you have to pull it all the way to one side or all the way to the other.

Hopefully I have explained my problem clearly - if there is anything I'm missing, I can provide more details.
Note that I am using com.aurelhubert.ahbottomnavigation.AHBottomNavigation
Here are the relevant files:

MainActivity.java:

public class MainActivity extends AppCompatActivity{

private AHBottomNavigationAdapter navigationAdapter;
private AHBottomNavigationViewPager viewPager;
private AHBottomNavigation bottomNavigation;

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

    // Add menu items to bar
    bottomNavigation = (AHBottomNavigation) findViewById(R.id.bottom_navigation);
    this.createNavItems();

    bottomNavigation.setOnTabSelectedListener(new AHBottomNavigation.OnTabSelectedListener() {
        @Override
        public boolean onTabSelected(int position, boolean wasSelected) {

            //show fragment
            if (position==0)
            {
                FirstFragment firstFragment=new FirstFragment();
                getSupportFragmentManager().beginTransaction().replace(R.id.content_id,firstFragment).commit();
            }else  if (position==1)
            {
                SecondFragment secondFragment=new SecondFragment();
                getSupportFragmentManager().beginTransaction().replace(R.id.content_id, secondFragment).commit();
            }else  if (position==2)
            {
                ThirdFragment thirdFragment=new ThirdFragment();
                getSupportFragmentManager().beginTransaction().replace(R.id.content_id,thirdFragment).commit();
            }else{
                FourthFragment fourthFragment=new FourthFragment();
                getSupportFragmentManager().beginTransaction().replace(R.id.content_id,fourthFragment).commit();
            }

            return true;
        }
    });
}

private void createNavItems(){
    navigationAdapter = new AHBottomNavigationAdapter(this, R.menu.navigation);
    navigationAdapter.setupWithBottomNavigation(bottomNavigation);

    // set current item
    bottomNavigation.setCurrentItem(0);
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/content_id"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <com.aurelhubert.ahbottomnavigation.AHBottomNavigation
        android:id="@+id/bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"/>

</android.support.design.widget.CoordinatorLayout>

FirstFragment.java:

public class FirstFragment extends Fragment {

    private FragmentActivity mContext;

    public FirstFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_first, container, false);

    }

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

        // Set the content of the activity to use the activity_main.xml layout file
        //setContentView(R.layout.activity_first);

        // Find the view pager that will allow the user to swipe between fragments
        ViewPager viewPager = (ViewPager) getView().findViewById(R.id.viewpager);

        // Create an adapter that knows which fragment should be shown on each page
        // using getFragmentManager() will work too
        FirstFragmentPagerAdapter adapter = new FirstFragmentPagerAdapter(mContext.getSupportFragmentManager(), mContext);

        // Set the adapter onto the view pager
        viewPager.setAdapter(adapter);

        TabLayout tabLayout = (TabLayout) getView().findViewById(R.id.sliding_tabs);
        tabLayout.setupWithViewPager(viewPager);
    }

    /**
     * Override to set context.  This context is used for getSupportFragmentManager in onCreateView
     * @param activity
     */
    @Override
    public void onAttach(Activity activity) {
        mContext=(FragmentActivity) activity;
        super.onAttach(activity);
    }

}

fragment_first.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

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

        <android.support.design.widget.TabLayout
            android:id="@+id/sliding_tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabMode="fixed"
            app:tabBackground="@color/firstTabBackground"
            app:tabIndicatorColor="@color/firstTabIndicatorColor"/>

        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="0px"
            android:layout_weight="1"/>

    </LinearLayout>


</android.support.constraint.ConstraintLayout>

FirstFragmentPagerAdapter.java:

public class FirstFragmentPagerAdapter extends FragmentPagerAdapter {

    private Context context;

    public FirstFragmentPagerAdapter(FragmentManager fm, Context mContext){
        super(fm);
        context = mContext;
    }


    /**
     * The ViewPager asks the adapter for the fragment at a given position,
     * i.e. for the 1st fragment, the ViewPager asks for the fragment at
     * position 1.
     * @param position
     * @return
     */
    @Override
    public Fragment getItem(int position){
        if (position == 0){
            return new FirstTabInFirstFragmentFragment();
        }
        else{
            return new SecondTabInFirstFragmentFragment();
        }
    }

    /**
     * On launch, the ViewPager asks the adapter how many pages there will be.
     * Here, our adapter returns how many pages there will be.
     * @return
     */
    @Override
    public int getCount() {return 2;}

    @Override
    public CharSequence getPageTitle(int position) {

        switch(position){
            case 0:
                return context.getResources().getString(R.string.first_tab_in_first_fragment_page_title);
            case 1:
                return context.getResources().getString(R.string.second_tab_in_first_fragment_page_title);
            default:
                return null;
        }
    }
}
Paradox
  • 4,602
  • 12
  • 44
  • 88
  • Actually Fragment gets detached when u click on First Tab after clicking the second tab. I would like to know from where are u getting R.id.content_id ? – Chandan kushwaha Jan 30 '18 at 03:41
  • @Chandankushwaha Now that you mention it, I'm not seeing it anywhere else in my project. I had been using this tutorial which had that code snipped: http://camposha.info/source/android-bottom-navigation-listview-source/ As you can probably tell, I'm very new to Android development. – Paradox Jan 30 '18 at 04:03

2 Answers2

5

I was able to solve this in two steps. First, in my Main Activiy method createNavItems, in addition to doing a bottomNavigation.setCurrentItem(0);, I also had to manually update the CoordinatorLayout (which has ID content_id) with the default fragment:

getSupportFragmentManager().beginTransaction().replace(R.id.content_id, new FirstFragment()).commit();

Next, to solve the TabLayout issues I had to change this line:

FirstFragmentPagerAdapter adapter = new FirstFragmentPagerAdapter(mContext.getSupportFragmentManager(), mContext);

to

FirstFragmentPagerAdapter adapter = new FirstFragmentPagerAdapter(getChildFragmentManager(), mContext);

The reason for this is that when nesting Fragments inside of other Fragments with ViewPager, getFragmentManager() is for managing Fragments within a Fragment whereas mContext.getSupportFragmentManager() is used for Activities.

Paradox
  • 4,602
  • 12
  • 44
  • 88
3

Firstly, Inorder to initially load the frstfragment on startup, u have to define the frstfragments view as default view to mainactivitys view.

Secondly, you need to have a framelayout to load the views for each fragment when selecting bottomnavigation menu.. here you are simply replacing the parent layout of mainactivity, which is a wrong concept, i believe.

So you need to create a child framelayout to load fragment views for each bottomnavigation menu items.

edits:

my layout which contains bottomnavigation,

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/content_home"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/app_bar_home"
android:keepScreenOn="false">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/ll_toolbar_home_search">

    <android.support.v7.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary">
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:background="@drawable/btn_style_white"
            android:layout_marginRight="10dp">
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_search"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:text="Search 18000+ products"
                android:id="@+id/tv_search_home"/>
        </LinearLayout>

    </android.support.v7.widget.Toolbar>

</LinearLayout>


<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/ll_toolbar_home_search"
    android:layout_above="@+id/navigation"
    android:id="@+id/frame_layout_fragment"
    android:background="@color/white">
</FrameLayout>

<com.aurelhubert.ahbottomnavigation.AHBottomNavigation
    android:id="@+id/navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true" />

</RelativeLayout>

and java class for that activity( only method that contains bottomnavigation manipulations) is follows:

private void BottomView1() {
    navigation = (AHBottomNavigation) findViewById(R.id.navigation);

    AHBottomNavigationItem item1 = new AHBottomNavigationItem("Home", R.drawable.ic_home, R.color.ash);
    AHBottomNavigationItem item2 = new AHBottomNavigationItem("Category", R.drawable.ic_category, R.color.ash);
    AHBottomNavigationItem item3 = new AHBottomNavigationItem("Search", R.drawable.ic_search, R.color.ash);
    AHBottomNavigationItem item4 = new AHBottomNavigationItem("Offers", R.drawable.ic_offers, R.color.ash);
    AHBottomNavigationItem item5 = new AHBottomNavigationItem("Cart", R.drawable.ic_cart, R.color.ash);

    navigation.addItem(item1);
    navigation.addItem(item2);
    navigation.addItem(item3);
    navigation.addItem(item4);
    navigation.addItem(item5);

    navigation.setCurrentItem(getResources().getColor(R.color.colorPrimaryDark));

    navigation.setTitleState(AHBottomNavigation.TitleState.ALWAYS_SHOW);

    setCartNotification();

    navigation.setAccentColor(getResources().getColor(R.color.colorPrimaryDark));

    navigation.setOnTabSelectedListener(new AHBottomNavigation.OnTabSelectedListener() {
        @Override
        public boolean onTabSelected(int position, boolean wasSelected) {
            Intent ii ;
            Fragment selectedFragment = null;
            if(position==0){
                selectedFragment = HomeFragment.newInstance();
                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
                transaction.replace(R.id.frame_layout_fragment, selectedFragment);
                transaction.commit();
            } else if(position==1){
                ii = new Intent(HomeActivity.this, ShopByCategoryActivity.class);
                startActivity(ii);
            } else if(position==2){
                ii = new Intent(HomeActivity.this, SearchActivity.class);
                startActivity(ii);
            } else if(position==3){
                ii = new Intent(HomeActivity.this, OffersActivity.class);
                startActivity(ii);
            } else if(position==4){
                ii = new Intent(HomeActivity.this, MyCartActivity.class);
                startActivity(ii);
            }
            return true;
        }
    });
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.frame_layout_fragment, HomeFragment.newInstance());
    transaction.commit();
}
Rashiq
  • 650
  • 1
  • 9
  • 23