Android implements the main interface of the bottom navigation bar
In mainstream apps, the main interface of the application is a navigation bar with multiple tabs at the bottom. Click to switch to the corresponding interface, as shown in the figure:
Next, the implementation process will be described.
1. The first is the analysis interface. On the bottom navigation bar, we can use a linear layout with full screen width, several labels wrapped in textview and horizontal orientation. At the top is a FrameLayout that takes up the remaining space.
activity_ main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" tools:context=".MainActivity" android:orientation="vertical"> <FrameLayout android:id="@+id/main_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1"/> <View android:layout_width="match_parent" android:layout_height="1px" android:background="@color/colorPrimaryDark" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:id="@+id/main_home" android:layout_width="wrap_content" android:layout_weight="1" android:layout_height="wrap_content" android:gravity="center" android:padding="20dp" android:text="首页" /> <View android:layout_width="1px" android:layout_height="match_parent" android:background="@color/colorPrimaryDark" /> <TextView android:id="@+id/main_game" android:layout_width="wrap_content" android:layout_weight="1" android:layout_height="wrap_content" android:gravity="center" android:padding="20dp" android:text="游戏" /> <View android:layout_width="1px" android:layout_height="match_parent" android:background="@color/colorPrimaryDark" /> <TextView android:id="@+id/main_video" android:layout_width="wrap_content" android:layout_weight="1" android:layout_height="wrap_content" android:gravity="center" android:padding="20dp" android:text="视频" /> <View android:layout_width="1px" android:layout_height="match_parent" android:background="@color/colorPrimaryDark" /> <TextView android:id="@+id/main_mine" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:padding="20dp" android:text="我的" /> </LinearLayout> </LinearLayout>
2. Four tags correspond to four fragments. We can create four fragments and put a textview in the layout for differentiation.
private HomeFragment homeFragment; private GameFragment gameFragment; private VideoFragment videoFragment; private mineFragment mineFragment;
3. Open mainactivity and initialize the control first
private void initView() { home= findViewById(R.id.main_home); game= findViewById(R.id.main_game); video= findViewById(R.id.main_video); mine= findViewById(R.id.main_mine); layout= findViewById(R.id.main_layout); home.setOnClickListener(this); game.setOnClickListener(this); video.setOnClickListener(this); mine.setOnClickListener(this); }
Onclick click events are processed later
3. Initialize four fragments
Our original intention is that after the fragment is loaded once, repeated clicks or switching back will not load again to consume resources. The common processing methods here include lazy loading of viewpager and hide and show of fragment. Here we explain the implementation of the latter.
private void initFragment() { FragmentTransaction transaction= getSupportFragmentManager().beginTransaction(); if (homeFragment!= null&& homeFragment.isAdded()){ transaction.remove(homeFragment); } if (gameFragment!= null&& gameFragment.isAdded()){ transaction.remove(gameFragment); } if (videoFragment!= null&& videoFragment.isAdded()){ transaction.remove(videoFragment); } if (mineFragment!= null&& mineFragment.isAdded()){ transaction.remove(mineFragment); } transaction.commitAllowingStateLoss(); homeFragment= null; gameFragment= null; videoFragment= null; mineFragment= null; home.performClick(); }
Let's analyze the code line by line
Start a transaction first
FragmentTransaction transaction= getSupportFragmentManager().beginTransaction();
Non null processing of fragment
if (homeFragment!= null&& homeFragment.isAdded()){ transaction.remove(homeFragment); } if (gameFragment!= null&& gameFragment.isAdded()){ transaction.remove(gameFragment); } if (videoFragment!= null&& videoFragment.isAdded()){ transaction.remove(videoFragment); } if (mineFragment!= null&& mineFragment.isAdded()){ transaction.remove(mineFragment); } transaction.commitAllowingStateLoss();
Set all fragments to null, and the click event of homefragment will be automatically executed, that is, homefragment will be displayed by default
homeFragment= null; gameFragment= null; videoFragment= null; mineFragment= null; home.performClick();
4. Back to the click events of the four bottom tabs, we execute the custom switchcontent method and pass in the view of the currently clicked tab as a parameter
@Override public void onClick(View view) { switch (view.getId()){ case R.id.main_home: switchContent(home); break; case R.id.main_game: switchContent(game); break; case R.id.main_video: switchContent(video); break; case R.id.main_mine: switchContent(mine); break; } }
5. Locate the switchcontent method
Create a new fragment object. When a tag is clicked, if the current fragment object is empty, an object instance corresponding to the fragment will be generated
public void switchContent(View view){ Fragment fragment; if (view== home){ if (homeFragment== null){ homeFragment= new HomeFragment(); } fragment= homeFragment; }else if (view== game){ if (gameFragment== null){ gameFragment= new GameFragment(); } fragment= gameFragment; }else if (view== video){ if (videoFragment== null){ videoFragment= new VideoFragment(); } fragment= videoFragment; }else if (view== mine){ if (mineFragment== null){ mineFragment= new mineFragment(); } fragment= mineFragment; }else { return; }
After generating the object, we can add and display the fragment.
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); if (mContent == null) { transaction.add(layout.getId(),fragment).commit(); mContent = fragment; } if (mContent != fragment) { if (!fragment.isAdded()) { transaction.hide(mContent).add(layout.getId(),fragment).commitAllowingStateLoss(); } else { transaction.hide(mContent).show(fragment).commitAllowingStateLoss(); } mContent = fragment; } home.setSelected(false); home.setSelected(false); home.setSelected(false); home.setSelected(false); view.setSelected(true);
When analyzing this code, we mainly compare the current fragment mcontent with the previous fragment, so as to judge whether the navigation bar at the bottom has been clicked for switching. First, when the application is opened, because we called the first tag automatic click method earlier.
home.performClick();
Look at the process, because mcontent is still null at this time, so go to this code
if (mContent == null) { transaction.add(layout.getId(),fragment).commit(); mContent = fragment; }
At this time, the fragment is the homefragment object. The page will display the homefragment and assign the object to mcontent.
At this point, the life cycle of homefragment is as follows. Everything is normal from attach() to onresume().
Next, click the second tab, where fragment is gamefragment and mcontent is homefragment. The two are different. Take this method.
if (mContent != fragment) { if (!fragment.isAdded()) { transaction.hide(mContent).add(layout.getId(),fragment).commitAllowingStateLoss(); } else { transaction.hide(mContent).show(fragment).commitAllowingStateLoss(); } mContent = fragment; }
Analyze the code. The gamefragment has not been loaded yet, so go first
transaction.hide(mContent).add(layout.getId(),fragment).commitAllowingStateLoss();
That is, hide the mcontent, that is, the homefragment, and display it when the gamefragment is loaded.
At this time, looking at the life cycle of gamefragment, everything is normal.
At this time, we click back to homefragment. At this time, fragment is homefragment, mcontent is gamefragment, and homefragment has been added, so we go
transaction.hide(mContent).show(fragment).commitAllowingStateLoss();
This statement refers to hiding the fragments without loading the fragments already loaded by add. You can directly show them. The commitallowingstateloss method is similar to the commit method, which is more suitable for submitting work under frequent page switching to avoid crash.
At the same time, open the log and find that the homefragment has not been destroyed and overloaded, so we don't want to switch frequent loading.
This is all done, and the demo is attached!
Resource download
The above is the whole content of this article. I hope it will help you in your study, and I hope you will support us a lot.