How to copy YouTube's app navigation logic

Multi tool use
Multi tool use


How to copy YouTube's app navigation logic



I want to implement in my app navigation logic like in Youtube app. (BottomNavigationView + Fragment management). I want this, because these fragments are heavy, so I want them to be lazy initialized and then stored in backstack, I feel like YouTube is doing it this way. I have implemented BottomNagivationView but I have problems with Fragment Management.



My code:


bottomNavigationView.setOnTabSelectedListener { position, _ ->
setFragment(OnlinePageFragment.Page.values()[position])
}



where Pages is enum


enum class Page(index: Int, val klass: Class<*>) {
ONE(0, OnePageFragment::class.java),
TWO(1, TwoPageFragment::class.java),
THREE(2, ThreePageFragment::class.java)
}



and here is my setFragment function


fun setFragment(page: OnlinePageFragment.Page) {
var fragment: Fragment? = supportFragmentManager.findFragmentByTag(page.klass.name)
val tag = page.klass.name

if (fragment == null)
fragment = OnlinePageFragment.newInstance(page, null)

val ft = supportFragmentManager.beginTransaction()
with(ft) {
replace(R.id.fragmentContainer, fragment, tag)
addToBackStack(tag)
commit()
}

}

override fun onBackPressed() {
if (supportFragmentManager.backStackEntryCount == 1) finish()
else super.onBackPressed()
}



And it's working, but not as good as YouTube app. YouTube app has some magic behaviour i.e. it keeps only one transaction per each fragment, while my app allows to create "infinite" backstack of transactions. Do you have any ideas how it works in YouTube app ?




2 Answers
2



Without using view pager you can manage it.
I have implemented Please check this. https://github.com/sandeshsk/BackStackFragmentRedirectsToHome



Please update if there is any issue.



This is a method which assigns fragment


public void addFragment(FragmentManager fragmentManager,
Fragment fragment,
int containerId,boolean isFromHome){

fragmentManager.popBackStack(null,FragmentManager.POP_BACK_STACK_INCLUSIVE);

FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
if(isFromHome){
fragmentTransaction.replace(containerId,fragment);
}else{
fragmentTransaction.add(new HomeFragment(),"Home");
fragmentTransaction.addToBackStack("Home");
}
fragmentTransaction.replace(containerId,fragment).commit();

}



This is your navigation item listener


private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
addFragment(getSupportFragmentManager(), new HomeFragment(), R.id.frame, true);
}else{
getSupportFragmentManager().popBackStack();
}
return true;
case R.id.navigation_dashboard:
addFragment(getSupportFragmentManager(),new DashboardFragment(),R.id.frame,false);
return true;
case R.id.navigation_notifications:
addFragment(getSupportFragmentManager(),new NotificationFragment(),R.id.frame,false);
return true;
case R.id.navigation_setting:
addFragment(getSupportFragmentManager(),new SettingFragment(),R.id.frame,false);
return true;
}
return false;
}
};



onBackPressed method


@Override
public void onBackPressed() {
if(getSupportFragmentManager().getBackStackEntryCount()>0){
navigation.setSelectedItemId(R.id.navigation_home);
}else {
super.onBackPressed();
}
}



I guess the best way here is to use ViewPager to store root fragments. Navigation bar will change pages of ViewPager.


ViewPager


ViewPager



Root fragments will store content fragments inside their ChildFragmentManagersand implement logic of navigation between content fragments.


ChildFragmentManagers



Also you will need to implement logic of delegation backpress events from activity to root fragments, to perform navigation in their backstack.



UPD #1
Make sure, that root fragments are not destroyed inside ViewPager, use setOffscreenPageLimit()



UPD #2
If you don't want to use ViewPager, you can use code from this answer to manage root fragments.





ViewPager is my current implementation, and I wanted to change it since It's too heavy to load 3 fragments at once.
– Stachu Barański
Aug 7 '17 at 21:13





@StachuBarański if it's too heavy to load 3 fragments at start at first load only the first one and others populate with data if user swipes to see them.
– hardartcore
Aug 8 '17 at 6:18






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

62vumpkeJIeL ef,x1ky1fQp
W hlWbZYZ OarNYdb9Vh7jy0p bMcMXbFK0sacZyegH1vf k 4p kuxU0 xb X,xu1 EA5gFEHq7j9 4S2lrPE Kc

Popular posts from this blog

PySpark - SparkContext: Error initializing SparkContext File does not exist

django NoReverseMatch Exception

List of Kim Possible characters