简体   繁体   中英

How to inflate fragment's layout in AppCompatActivity.onCreate()?

Im creating a simple app to learn fragments. It consists of a bottomNavigationView with three menu items, and a FrameLayout thats serves as a containter for fragments and takes up the rest of the space. Selecting an item switches the Fragment in FrameLayout with:

getSupportFragmentManager().beginTransaction().replace(R.id.fragmentContainer,selectedFragment).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit();

When i ran the app, i noticed that transitions between fragments are very slow. Profiler revealed that it was due to inflation of the layout each time. So i modified onCreateView() method of fragments to inflate just once and then return already inflated layout.

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if(ui == null)
            inflateLayout(inflater, container);
        return ui;

    }

This fixed the issue partialy because first transition was still slow. I tried to inflate fragment UI in activity, but that resulted in an error: Fragment isn't attached to Context. So i just switched between all the fragments in onCreate() of main activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    BottomNavigationView nav = findViewById(R.id.bottom_nav);
    homeFragment = new HomeFragment();
    favFragment = new FavFragment();
    starFragment = new StarFragment();
    nav.setSelectedItemId(R.id.home);
    getSupportFragmentManager().beginTransaction().replace(R.id.fragmentContainer, starFragment).commit();
    getSupportFragmentManager().beginTransaction().replace(R.id.fragmentContainer, favFragment).commit();
    getSupportFragmentManager().beginTransaction().replace(R.id.fragmentContainer, homeFragment).commit();
    nav.setOnNavigationItemSelectedListener(listener);
}

That made things better, but recyclerView which is contained within StarFragment still creates viewHolders after the "real" transaction (initiated by listener), whitch takes 20ms for a single viewHolder (i'll look into why later).

My question is: how to make those transactions between fragments quick? Is what im trying to do right, or is there a better way?

I am not sure how complex your layouts are, however, loading UI elements in the layout of a fragment should not take much time if the data loaders (reading values for your RecyclerView from the database, network calls) are off-threaded.

You really do not have to do all the fragment transactions in the onCreate function of your activity. Just load the fragments (or do the fragment transaction) on demand when you click an item in the bottom navigation bar. You are creating instances of the fragment in your onCreate function which is perfectly fine and in that way, each time you are switching among fragments are not creating new instances of your fragment class.

I am not sure if the initial loading your fragments can be more optimized, however, you may consider having a ViewPager so that the fragments are loaded all the time after you are done with their first time loading.

Here's a good tutorial on how you can add a ViewPager with a bottom navigation bar. I hope that helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM