Reputation: 936
I created a new project with the "Bottom Navigation Activity":
This is the generated code:
package com.aaron.waller.mrpolitik;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView mTextMessage;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
mTextMessage.setText(R.string.title_home);
case R.id.navigation_dashboard:
mTextMessage.setText(R.string.title_dashboard);
case R.id.navigation_notifications:
mTextMessage.setText(R.string.title_notifications);
}
return true;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextMessage = (TextView) findViewById(R.id.message);
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}
}
How can I change to new Fragments with the Bottom Bar? For example I have 3 Fragments: Fragment1 Fragment2 and Fragment3 And I want to change to them with the 3 buttons from the Bottom Bar. Also I want that I can switch the Fragments by swiping my finger left and right how can I do that?
Upvotes: 27
Views: 72836
Reputation: 19
Its my suggest way and it has an ideal performance
I did it with using naveController
and androidx.navigation:navigation
Step 1: Add the navigation dependency to your app-level build.gradle
file. This will allow you to use the Navigation component in your app.
dependencies {
def nav_version = "2.3.5"
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
}
Step 2: Create a new menu resource file for the bottom navigation bar. This file will contain the menu items that will be displayed in the bar. To create a new menu resource file, right-click on the res folder in the Project panel, select New > Android resource file
, and set the Resource type to Menu.
Step 3: In the menu resource file, add the menu items that will be displayed in the bottom navigation bar. Each menu item should have a unique ID and a title. For example:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_home"
android:title="Home" />
<item
android:id="@+id/navigation_dashboard"
android:title="Dashboard" />
<item
android:id="@+id/navigation_notifications"
android:title="Notifications" />
Step 4: In the layout file where you want to display the bottom navigation bar, add a BottomNavigationView element. For example:
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_navigation_menu"
/>
Note that the app:menu attribute is set to the name of the menu resource file created in step 2.
Step 5: In your activity or fragment that will host the bottom navigation bar, create an instance of NavController using the findNavController() method and pass in the BottomNavigationView as the argument. For example:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:startDestination="@id/navigation_home">
<fragment
android:id="@+id/navigation_home"
android:name="com.example.myapp.HomeFragment"
android:label="@string/title_home" />
<fragment
android:id="@+id/navigation_dashboard"
android:name="com.example.myapp.DashboardFragment"
android:label="@string/title_dashboard" />
<fragment
android:id="@+id/navigation_notifications"
android:name="com.example.myapp.NotificationsFragment"
android:label="@string/title_notifications" />
Note that each fragment is identified by a unique ID, which corresponds to the ID of the menu item in the bottom navigation bar.
That's it! With these steps, you should now have a basic bottom navigation bar that can be used to replace different fragments in your app.
Upvotes: 1
Reputation: 351
There is another way to avoid recreating fragment -- fm.beginTransaction().hide(active).show(aimFragment)
My example is follow(just copy from my project recent):
public class MainActivity extends AppCompatActivity {
@BindView(R.id.main_bottom_navigation) BottomNavigationView mBottomNavigationView;
final Fragment mTaskListFragment = new TaskListFragment();
final Fragment mUserGroupFragment = new UserGroupFragment();
final Fragment mUserMeFragment = new UserMeFragment();
final FragmentManager fm = getSupportFragmentManager();
Fragment active = mTaskListFragment;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mBottomNavigationView
.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
fm.beginTransaction().add(R.id.main_fragment_container, mUserMeFragment, "3")
.hide(mUserMeFragment).commit();
fm.beginTransaction().add(R.id.main_fragment_container, mUserGroupFragment, "2")
.hide(mUserGroupFragment).commit();
fm.beginTransaction().add(R.id.main_fragment_container, mTaskListFragment, "1").commit();
}
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= item -> {
// TODO: 这种切换方式比较快,但横竖屏切换会出问题,已经
switch (item.getItemId()) {
case R.id.nav_list:
fm.beginTransaction().hide(active).show(mTaskListFragment).commit();
active = mTaskListFragment;
break;
case R.id.nav_group:
fm.beginTransaction().hide(active).show(mUserGroupFragment).commit();
active = mUserGroupFragment;
break;
case R.id.nav_me:
fm.beginTransaction().hide(active).show(mUserMeFragment).commit();
active = mUserMeFragment;
break;
}
return true;
};
}
It seems efficient and will work well until you rotate your phone. And I fixed it by adding the code following in the manifest file to the activity to retain the fragment state. (e.g. at AndroidManifest.xml
):
android:configChanges="screenSize|orientation|screenLayout"
Upvotes: 1
Reputation: 592
You can switch fragments through below code if you are using Jetpack Navigation.
val navController = findNavController(R.id.your_nav_host_fragment)
navController.navigate(R.id.your_fragment_id_in_menu)
For more information go through this doc : https://codelabs.developers.google.com/codelabs/android-navigation/#0
Upvotes: 7
Reputation: 2228
The easy way is with the Navigation Component:
bottom_navigation_view?.setupWithNavController(navController)
Upvotes: 2
Reputation: 254
The way I would do it is, I would first add three methods similar to this one (each for a single fragment. Replace the layout name and the fragment object to the appropriate fragment that is being switched to):
public void switchToFragment1() {
FragmentManager manager = getSupportFragmentManager();
manager.beginTransaction().replace(R.id.your_fragment_layout_name, new Fragment1()).commit();
}
So your switch statement would end up looking like this:
switch (item.getItemId()) {
case R.id.navigation_home:
mTextMessage.setText(R.string.title_home);
switchToFragment1();
break;
case R.id.navigation_dashboard:
mTextMessage.setText(R.string.title_dashboard);
switchToFragment2();
break;
case R.id.navigation_notifications:
mTextMessage.setText(R.string.title_notifications);
switchToFragment3();
break;
}
As for switching the fragments by swiping to the sides, I believe you would need a ViewPager.
Upvotes: 24
Reputation: 380
//fully tested
public class DashBoardActivity extends AppCompatActivity {
Fragment fragment = null;
FragmentTransaction fragmentTransaction;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
return true;
case R.id.navigation_dashboard:
fragment = new FragmentDashBoard();
switchFragment(fragment);
return true;
case R.id.navigation_notifications:
fragment = new FragmentNotification();
switchFragment(fragment);
return true;
}
return false;
}
};
private void switchFragment(Fragment fragment) {
fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content, fragment);
fragmentTransaction.commit();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
navigation.setSelectedItemId(R.id.navigation_dashboard);
}
}
Upvotes: 2
Reputation: 131
The best way is to use a ViewPager
with a FragmentPagerAdapter
. Since it cashes the fragments inside it. Use setOnNavigationItemSelectedListener
with the BottomNavigationView
to listen for the user's clicks. And use viewPager.setCurrentItem(..)
to move between pages.
Creating a new fragment everytime the user clicks on an item in the bottom navigation view isn't a good solution (especially when the user clicks on the item of the screen that he is currently at, the solution above will create a new fragment even for this case)
Upvotes: 9
Reputation: 27237
It's pretty "simple".
FragmentA
, FragmentB
and FragmentC
with FragmentA
being the first Fragment we want on the BottomNavigationView.In your Activity, go to the onNavigationItemSelected
method and change the content to this:
private BottomNavigationView.OnNavigationItemSelectedListener
mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener(){
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.frag_a:
currentFragment = new FragmentA();
ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content, currentFragment);
ft.commit();
return true;
case R.id.frag_b:
currentFragment = new FragmentB();
ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content, currentFragment);
ft.commit();
return true;
case R.id.frag_c:
currentFragment = new FragmentC();
ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content, currentFragment);
ft.commit();
return true;
}
return false;
}
};
In your onCreate()
method, do this:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client_profile);
ft = getSupportFragmentManager().beginTransaction();
currentFragment = new FragmentA();
ft.replace(R.id.content, currentFragment);
ft.commit();
BottomNavigationView navigation = (BottomNavigationView)
findViewById(R.id.navigation); navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}
If you do not add FragmentA
in the onCreate()
, the activity is blank when you first launch it.
If you are wondering what R.id.content
refers to, it is the Id of the Framelayout in your activity's layout. It initially contains a TextView
, delete the TextView so it looks like this:
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
Finally, ft
and currentFragment
are defined like this:
Fragment currentFragment = null;
FragmentTransaction ft;
Not sure about elegance, but this works.
Upvotes: 11
Reputation: 1
you can use this one
fragmentManager = getFragmentManager();
transaction = fragmentManager.beginTransaction();
FragmentA a = new FragmentA();
transaction.replace(R.id.frame, a);
transaction.commit();
Upvotes: -2