My app has an activity
with NavigationView
and for different items in the navigation drawer UI is changed by changing the fragment
. One such fragment has TabLayout
implemented in it.
When the app starts the fragment
with TabLayout
is loaded and it works fine but when I switch between different items in the navigation drawer
and then come back to the item which has the TabLayout
, now on swiping the tabs the indicator gets stuck in between tabs and the content on one tab is not even displayed. I have no clue regarding what mistake I might have did. I am using
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.android.support:design:24.2.1'
compile 'com.android.support:support-v4:24.2.1'
This is the activity which has the NavigationView (activity_start.xml)
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="@layout/app_bar_start"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_start"
app:menu="@menu/start_menu" />
</android.support.v4.widget.DrawerLayout>
This is the code for app_bar_start.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
android:fitsSystemWindows="true"
tools:context="com.optimilia.readaloud.Start">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay"
app:elevation="0dp">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
This is the fragment which has the TabLayout (fragment_home.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_home"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.optimilia.readaloud.HomeFragment">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="@dimen/custom_tab_layout_height"
app:tabMode="fixed"
app:tabGravity="fill"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</LinearLayout>
Start.java
public class Start extends AppCompatActivity {
private NavigationView navigationView;
private DrawerLayout drawer;
private Toolbar toolbar;
private Fragment homeFragment = null;
// index to identify current nav menu item
public static int navItemIndex = 0;
// tags used to attach the fragments
private static final String TAG_HOME = "Home";
private static final String TAG_STORE = "Store";
private static final String TAG_ABOUT = "About";
private static final String TAG_SETTINGS = "Settings";
private static final String TAG_HELP = "Help";
public static String CURRENT_TAG = TAG_HOME;
// toolbar titles respected to selected nav menu item
private String[] activityTitles;
private Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mHandler = new Handler(this.getMainLooper());
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
navigationView = (NavigationView) findViewById(R.id.nav_view);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
// load toolbar titles from string resources
activityTitles = getResources().getStringArray(R.array.nav_item_activity_titles);
// initializing navigation menu
setUpNavigationView();
if (savedInstanceState == null) {
navItemIndex = 0;
CURRENT_TAG = TAG_HOME;
loadFragment(true);
}
}
private void loadFragment(boolean selectNavMenu) {
if (selectNavMenu) {
selectNavMenu();
}
// set toolbar title
setToolbarTitle();
// if user select the current navigation menu again, don't do anything
// just close the navigation drawer
if (getSupportFragmentManager().findFragmentByTag(CURRENT_TAG) != null) {
drawer.closeDrawers();
return;
}
// Sometimes, when fragment has huge data, screen seems hanging
// when switching between navigation menus
// So using runnable, the fragment is loaded with cross fade effect
Runnable mPendingRunnable = new Runnable() {
@Override
public void run() {
// update the main content by replacing fragments
Fragment fragment = getFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
fragmentTransaction.replace(R.id.frame, fragment, CURRENT_TAG);
fragmentTransaction.commit();
}
};
// If mPendingRunnable is not null, then add to the message queue
if (mPendingRunnable != null) {
mHandler.post(mPendingRunnable);
}
drawer.closeDrawers();
invalidateOptionsMenu();
}
private Fragment getFragment() {
switch (navItemIndex) {
case 0:
if (homeFragment == null) {
homeFragment = new HomeFragment();
}
return homeFragment;
case 1:
SettingsFragment settingsFragment = new SettingsFragment();
return settingsFragment;
// case 2:
// // movies fragment
// MoviesFragment moviesFragment = new MoviesFragment();
// return moviesFragment;
// case 3:
// // notifications fragment
// NotificationsFragment notificationsFragment = new NotificationsFragment();
// return notificationsFragment;
//
// case 4:
// // settings fragment
// SettingsFragment settingsFragment = new SettingsFragment();
// return settingsFragment;
default:
return new HomeFragment();
}
}
private void setToolbarTitle() {
getSupportActionBar().setTitle(activityTitles[navItemIndex]);
}
private void selectNavMenu() {
try {
navigationView.getMenu().getItem(navItemIndex).setChecked(true);
}
catch (Exception ex){}
}
private void setUpNavigationView() {
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
// This method will trigger on item Click of navigation menu
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
//Check to see which item was being clicked and perform appropriate action
switch (menuItem.getItemId()) {
//Replacing the main content with ContentFragment Which is our Inbox View;
case R.id.nav_home:
navItemIndex = 0;
CURRENT_TAG = TAG_HOME;
break;
case R.id.nav_settings:
navItemIndex = 1;
CURRENT_TAG = TAG_SETTINGS;
break;
case R.id.nav_store:
navItemIndex = 2;
CURRENT_TAG = TAG_STORE;
break;
case R.id.nav_help:
navItemIndex = 3;
CURRENT_TAG = TAG_HELP;
break;
case R.id.nav_about:
navItemIndex = 4;
CURRENT_TAG = TAG_ABOUT;
break;
default:
navItemIndex = 0;
}
//Checking if the item is in checked state or not, if not make it in checked state
if (menuItem.isChecked()) {
menuItem.setChecked(false);
} else {
menuItem.setChecked(true);
}
menuItem.setChecked(true);
loadFragment(false);
return true;
}
});
}
@Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawers();
return;
}
super.onBackPressed();
}
}
HomeFragment.java
public class HomeFragment extends Fragment {
private View currView;
private TabLayout tabLayout;
private ViewPager viewPager;
private int[] tabIcons = {
R.drawable.ic_start,
R.drawable.ic_recent,
R.drawable.ic_reading_list
};
public HomeFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
currView = inflater.inflate(R.layout.fragment_home, container, false);
viewPager = (ViewPager) currView.findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) currView.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
setupTabIcons();
return currView;
}
private void setupViewPager(ViewPager viewPager) {
HomeFragment.ViewPagerAdapter adapter = new HomeFragment.ViewPagerAdapter(getFragmentManager());
adapter.addFragment(new StartFragment(), "Start");
adapter.addFragment(new RecentFragment(), "Recent");
adapter.addFragment(new ReadingListFragment(), "Reading list");
viewPager.setAdapter(adapter);
}
private void setupTabIcons() {
tabLayout.getTabAt(0).setIcon(tabIcons[0]);
tabLayout.getTabAt(1).setIcon(tabIcons[1]);
tabLayout.getTabAt(2).setIcon(tabIcons[2]);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
In
HomeFragment.java
was usinggetFragmentManager()
forViewPagerAdapter
and this was causing the problem. On switching togetChildFragmentManager()
it started working perfectly.