I\'m trying to get the new TabLayout in the android design library working.
I\'m following this post:
http://android-developers.blogspot.com/2015/05/android
I am facing some issue with menu change when fragment changes in ViewPager. I ended up implemented below code.
DashboardFragment
public class DashboardFragment extends BaseFragment {
private Context mContext;
private TabLayout mTabLayout;
private ViewPager mViewPager;
private DashboardPagerAdapter mAdapter;
private OnModuleChangeListener onModuleChangeListener;
private NavDashBoardActivity activityInstance;
public void setOnModuleChangeListener(OnModuleChangeListener onModuleChangeListener) {
this.onModuleChangeListener = onModuleChangeListener;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.dashboard_fragment, container, false);
}
//pass -1 if you want to get it via pager
public Fragment getFragmentFromViewpager(int position) {
if (position == -1)
position = mViewPager.getCurrentItem();
return ((Fragment) (mAdapter.instantiateItem(mViewPager, position)));
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mContext = getActivity();
activityInstance = (NavDashBoardActivity) getActivity();
mTabLayout = (TabLayout) view.findViewById(R.id.tab_layout);
mViewPager = (ViewPager) view.findViewById(R.id.view_pager);
final List moduleToShow = getModuleToShowList();
mViewPager.setOffscreenPageLimit(moduleToShow.size());
for(EnumUtils.Module module :moduleToShow)
mTabLayout.addTab(mTabLayout.newTab().setText(EnumUtils.Module.getTabText(module)));
updateTabPagerAndMenu(0 , moduleToShow);
mAdapter = new DashboardPagerAdapter(getFragmentManager(),moduleToShow);
mViewPager.setOffscreenPageLimit(mAdapter.getCount());
mViewPager.setAdapter(mAdapter);
mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(final TabLayout.Tab tab) {
mViewPager.post(new Runnable() {
@Override
public void run() {
mViewPager.setCurrentItem(tab.getPosition());
}
});
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//added to redraw menu on scroll
}
@Override
public void onPageSelected(int position) {
updateTabPagerAndMenu(position , moduleToShow);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
//also validate other checks and this method should be in SharedPrefs...
public static List getModuleToShowList(){
List moduleToShow = new ArrayList<>();
moduleToShow.add(EnumUtils.Module.HOME);
moduleToShow.add(EnumUtils.Module.ABOUT);
return moduleToShow;
}
public void setCurrentTab(final int position){
if(mViewPager != null){
mViewPager.postDelayed(new Runnable() {
@Override
public void run() {
mViewPager.setCurrentItem(position);
}
},100);
}
}
private Fragment getCurrentFragment(){
return mAdapter.getCurrentFragment();
}
private void updateTabPagerAndMenu(int position , List moduleToShow){
//it helps to change menu on scroll
//http://stackoverflow.com/a/27984263/3496570
//No effect after changing below statement
ActivityCompat.invalidateOptionsMenu(getActivity());
if(mTabLayout != null)
mTabLayout.getTabAt(position).select();
if(onModuleChangeListener != null){
if(activityInstance != null){
activityInstance.updateStatusBarColor(
EnumUtils.Module.getStatusBarColor(moduleToShow.get(position)));
}
onModuleChangeListener.onModuleChanged(moduleToShow.get(position));
mTabLayout.setSelectedTabIndicatorColor(EnumUtils.Module.getModuleColor(moduleToShow.get(position)));
mTabLayout.setTabTextColors(ContextCompat.getColor(mContext,android.R.color.black)
, EnumUtils.Module.getModuleColor(moduleToShow.get(position)));
}
}
}
dashboardfragment.xml
DashboardPagerAdapter
public class DashboardPagerAdapter extends FragmentPagerAdapter {
private List moduleList;
private Fragment mCurrentFragment = null;
public DashboardPagerAdapter(FragmentManager fm, List moduleList){
super(fm);
this.moduleList = moduleList;
}
@Override
public Fragment getItem(int position) {
return EnumUtils.Module.getDashboardFragment(moduleList.get(position));
}
@Override
public int getCount() {
return moduleList.size();
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
if (getCurrentFragment() != object) {
mCurrentFragment = ((Fragment) object);
}
super.setPrimaryItem(container, position, object);
}
public Fragment getCurrentFragment() {
return mCurrentFragment;
}
public int getModulePosition(EnumUtils.Module moduleName){
for(int x = 0 ; x < moduleList.size() ; x++){
if(moduleList.get(x).equals(moduleName))
return x;
}
return -1;
}
}
And in each page of Fragment setHasOptionMenu(true) in onCreate and implement onCreateOptionMenu. then it will work properly.
dASHaCTIVITY
public class NavDashBoardActivity extends BaseActivity
implements NavigationView.OnNavigationItemSelectedListener {
private Context mContext;
private DashboardFragment dashboardFragment;
private Toolbar mToolbar;
private DrawerLayout drawer;
private ActionBarDrawerToggle toggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nav_dash_board);
mContext = NavDashBoardActivity.this;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().setStatusBarColor(ContextCompat.getColor(mContext,R.color.yellow_action_bar));
}
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
updateToolbarText(new ToolbarTextBO("NCompass " ,""));
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
toggle = new ActionBarDrawerToggle(
this, drawer, mToolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
//onclick of back button on Navigation it will popUp fragment...
toggle.setToolbarNavigationClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(!toggle.isDrawerIndicatorEnabled()) {
getSupportFragmentManager().popBackStack();
}
}
});
final NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setItemIconTintList(null);//It helps to show icon on Navigation
updateNavigationMenuItem(navigationView);
navigationView.setNavigationItemSelectedListener(this);
//Left Drawer Upper Section
View headerLayout = navigationView.getHeaderView(0); // 0-index header
TextView userNameTv = (TextView) headerLayout.findViewById(R.id.tv_user_name);
userNameTv.setText(AuthSharePref.readUserLoggedIn().getFullName());
RoundedImageView ivUserPic = (RoundedImageView) headerLayout.findViewById(R.id.iv_user_pic);
ivUserPic.setImageResource(R.drawable.profile_img);
headerLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//close drawer and add a fragment to it
drawer.closeDrawers();//also try other methods..
}
});
//ZA code starts...
dashboardFragment = new DashboardFragment();
dashboardFragment.setOnModuleChangeListener(new OnModuleChangeListener() {
@Override
public void onModuleChanged(EnumUtils.Module module) {
if(mToolbar != null){
mToolbar.setBackgroundColor(EnumUtils.Module.getModuleColor(module));
if(EnumUtils.Module.getMenuID(module) != -1)
navigationView.getMenu().findItem(EnumUtils.Module.getMenuID(module)).setChecked(true);
}
}
});
addBaseFragment(dashboardFragment);
backStackListener();
}
public void updateStatusBarColor(int colorResourceID){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().setStatusBarColor(colorResourceID);
}
}
private void updateNavigationMenuItem(NavigationView navigationView){
List modules = DashboardFragment.getModuleToShowList();
if(!modules.contains(EnumUtils.Module.MyStores)){
navigationView.getMenu().findItem(R.id.nav_my_store).setVisible(false);
}
if(!modules.contains(EnumUtils.Module.Livewall)){
navigationView.getMenu().findItem(R.id.nav_live_wall).setVisible(false);
}
}
private void backStackListener(){
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
if(getSupportFragmentManager().getBackStackEntryCount() >= 1)
{
toggle.setDrawerIndicatorEnabled(false); //disable "hamburger to arrow" drawable
toggle.setHomeAsUpIndicator(R.drawable.ic_arrow_back_black_24dp); //set your own
///toggle.setDrawerArrowDrawable();
///toggle.setDrawerIndicatorEnabled(false); // this will hide hamburger image
///Toast.makeText(mContext,"Update to Arrow",Toast.LENGTH_SHORT).show();
}
else{
toggle.setDrawerIndicatorEnabled(true);
}
if(getSupportFragmentManager().getBackStackEntryCount() >0){
if(getCurrentFragment() instanceof DashboardFragment){
Fragment subFragment = ((DashboardFragment) getCurrentFragment())
.getViewpager(-1);
}
}
else{
}
}
});
}
private void updateToolBarTitle(String title){
getSupportActionBar().setTitle(title);
}
public void updateToolBarColor(String hexColor){
if(mToolbar != null)
mToolbar.setBackgroundColor(Color.parseColor(hexColor));
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (drawer.isDrawerOpen(GravityCompat.START))
getMenuInflater().inflate(R.menu.empty, menu);
return super.onCreateOptionsMenu(menu);//true is wriiten first..
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == android.R.id.home)
{
if (drawer.isDrawerOpen(GravityCompat.START))
drawer.closeDrawer(GravityCompat.START);
else {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
} else
drawer.openDrawer(GravityCompat.START);
}
return false;///true;
}
return false;// false so that fragment can also handle the menu event. Otherwise it is handled their
///return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_my_store) {
// Handle the camera action
dashboardFragment.setCurrentTab(EnumUtils.Module.MyStores);
}
}else if (id == R.id.nav_log_out) {
Dialogs.logOut(mContext);
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
public void updateToolbarText(ToolbarTextBO toolbarTextBO){
mToolbar.setTitle("");
mToolbar.setSubtitle("");
if(toolbarTextBO.getTitle() != null && !toolbarTextBO.getTitle().isEmpty())
mToolbar.setTitle(toolbarTextBO.getTitle());
if(toolbarTextBO.getDescription() != null && !toolbarTextBO.getDescription().isEmpty())
mToolbar.setSubtitle(toolbarTextBO.getDescription());*/
}
@Override
public void onPostCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
super.onPostCreate(savedInstanceState, persistentState);
// Sync the toggle state after onRestoreInstanceState has occurred.
toggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
toggle.onConfigurationChanged(newConfig);
}
}