[英]How to change fragment with the Bottom Navigation Activity?
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.
例如,我有 3 个 Fragment:Fragment1 Fragment2 和 Fragment3 我想用底部栏中的 3 个按钮更改它们。 Also I want that I can switch the Fragments by swiping my finger left and right how can I do that?
另外我希望我可以通过左右滑动手指来切换片段,我该怎么做?
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 语句最终看起来像这样:
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 .至于通过向两侧滑动来切换片段,我相信您需要一个ViewPager 。
It's pretty "simple".这非常“简单”。
FragmentA
, FragmentB
and FragmentC
with FragmentA
being the first Fragment we want on the BottomNavigationView. FragmentA
、 FragmentB
和FragmentC
其中FragmentA
是我们想要在 BottomNavigationView 上的第一个 Fragment。 In your Activity, go to the onNavigationItemSelected
method and change the content to this:在您的 Activity 中,转到
onNavigationItemSelected
方法并将内容更改为:
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:在您的
onCreate()
方法中,执行以下操作:
@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.如果您没有在
onCreate()
添加FragmentA
,那么当您第一次启动它时该活动是空白的。
If you are wondering what R.id.content
refers to, it is the Id of the Framelayout in your activity's layout.如果您想知道
R.id.content
指的是什么,它是您活动布局中 Framelayout 的 Id。 It initially contains a TextView
, delete the TextView so it looks like this:它最初包含一个
TextView
,删除 TextView 使其看起来像这样:
<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:最后,
ft
和currentFragment
定义如下:
Fragment currentFragment = null;
FragmentTransaction ft;
Not sure about elegance, but this works.不确定优雅,但这是有效的。
The best way is to use a ViewPager
with a FragmentPagerAdapter
.最好的方法是使用带有
FragmentPagerAdapter
的ViewPager
。 Since it cashes the fragments inside it.因为它兑现了里面的碎片。 Use
setOnNavigationItemSelectedListener
with the BottomNavigationView
to listen for the user's clicks.使用
setOnNavigationItemSelectedListener
和BottomNavigationView
来监听用户的点击。 And use viewPager.setCurrentItem(..)
to move between pages.并使用
viewPager.setCurrentItem(..)
在页面之间移动。
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)每次用户点击底部导航视图中的项目时创建一个新片段并不是一个好的解决方案(特别是当用户点击他当前所在屏幕的项目时,上面的解决方案将创建一个新片段,即使是这个案例)
//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);
}
}
简单的方法是使用导航组件:
bottom_navigation_view?.setupWithNavController(navController)
You can switch fragments through below code if you are using Jetpack Navigation.如果您使用 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有关更多信息,请参阅此文档: https : //codelabs.developers.google.com/codelabs/android-navigation/#0
There is another way to avoid recreating fragment -- fm.beginTransaction().hide(active).show(aimFragment)
还有另一种避免重新创建片段的方法
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.
我通过将清单文件中的以下代码添加到活动以保留片段状态来修复它。 (eg at
AndroidManifest.xml
): (例如在
AndroidManifest.xml
):
android:configChanges="screenSize|orientation|screenLayout"
you can use this one你可以用这个
fragmentManager = getFragmentManager();
transaction = fragmentManager.beginTransaction();
FragmentA a = new FragmentA();
transaction.replace(R.id.frame, a);
transaction.commit();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.