在BottomNavigationView中切换Fragment

4
我正在使用底部导航视图制作一个简单的应用程序,其中包含3个片段(布局和Java)。我在MainActivity.java中声明了BottonNavigationView。我的bottonnavigation有3个项目,对应3个片段。因此,在我的MainActivity.java中,当我选择一个项目时,它会启动一个片段。所以,当我再次选择另一个项目时,什么也不会发生,因为在java片段中,我需要声明BottonNavigationView,但我不知道如何设置它以切换实际片段与另一个片段。
我尝试了这个链接,但没有成功:https://developer.android.com/training/basics/fragments/fragment-ui.html 抱歉我的英语不好
下面是代码:
主活动
 @Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    Fragment selectedFragment = null;
    switch (item.getItemId()) {
        case R.id.navigation_home:
            selectedFragment = HomeFragment.newInstance();
            break;
        case R.id.navigation_dashboard:
            selectedFragment = DashboardFragment.newInstance();
            break;
        case R.id.navigation_notifications:
            selectedFragment = NotificationsFragment.newInstance();
            break;
    }
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.content, selectedFragment);
    transaction.commit();
    return true;
}

Java片段示例

public class HomeFragment extends Fragment {
public static HomeFragment newInstance() {
HomeFragment fragment = new HomeFragment();
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.navigation_home, container, false);
return inflater.inflate(R.layout.navigation_home, container, false);
}

在我的main_activity布局中,我有一个包含FrameLayout和BottomNavigationView的LinearLayout,我认为我需要创建一个新实例,对吗? - Tony Starkus
你可以创建代码片段,并且可以重复使用它们。 - PeerNet
@Yupi 我只有一个TextView用于片段(文本是片段名称)。id内容是我的activity_main.xml布局中的framelayout。 - Tony Starkus
@TonyStarkus 覆盖 onBackPressed() 并实现所需的代码。 - Yupi
像这样: @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK)) { HomeFragment.newInstance(); return true; } return super.onKeyDown(keyCode, event); } - Tony Starkus
显示剩余7条评论
6个回答

9
你可以尝试一下:

您可以尝试它:

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    Fragment selectedFragment = null;
    switch (item.getItemId()) {
        case R.id.navigation_home:
            selectedFragment = HomeFragment.newInstance();
            break;
        case R.id.navigation_dashboard:
            selectedFragment = DashboardFragment.newInstance();
            break;
        case R.id.navigation_notifications:
            selectedFragment = NotificationsFragment.newInstance();
            break;
    }
    getSupportFragmentManager().beginTransaction().replace(R.id.content, selectedFragment).commit();
    return true;
}

1
哇,伙计,看起来好像可以了,谢谢。只有一个问题:我有三个片段(主页、仪表板和通知)。主页片段是我的应用程序的主菜单。因此,如果我在仪表板或通知中,并按下按钮,则希望将onKeyDown设置为返回主页片段,在主页片段中,如果我按下返回按钮,则希望关闭应用程序。你知道怎么做吗? - Tony Starkus
谢谢 @Thien,有很多代码,但我会尝试它们。谢谢 - Tony Starkus
@ThienHuynh 你在第一次运行时如何设置片段的初始值? - RazorHead
@ThienHuynh 抱歉,我想问的是如何在活动首次启动时加载初始片段。您的建议会激活底部导航栏。 - RazorHead
等等,这跟问题中提到的原始帖有什么不同吗?我有什么遗漏的吗?我看不出任何区别。 - Syed Ahmed Jamil
显示剩余2条评论

6

2
在这种情况下,最好尝试从fragmentManager获取现有片段,例如fragmentManager.findFragmentByTag(tag)。这样可以更流畅地切换,并且不需要加载网络上的某些内容(如果您在片段或片段的呈现器中有这样的代码)。

0

你应该为每个Fragment创建一个新的实例。然后隐藏当前活动的Fragment,显示新的Fragment。

    Fragment activeFragment;
    ArrayList<Fragment> fragment;

public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            Fragment selectedFragment = null;
            switch (item.getItemId()) {
                case R.id.navigation_fragment:
                    selectedFragment = ShowMyFragment.newInstance();
                    replaceFragment(selectedFragment);
                    return true;
}
});
    private void replaceFragment(Fragment selectedFragment) {
        boolean lastOpened = false;
        for ( int i=0; i<fragment.size();i++ )
        {
            if ( fragment.get(i) == selectedFragment ) {
                lastOpened = true;
                break;
            }
        }
        if (!lastOpened) {
            getSupportFragmentManager().beginTransaction().replace(R.id.content, selectedFragment).commit();
        }
        else
        {
            getSupportFragmentManager().beginTransaction().hide(activeFragment).show(selectedFragment).commit();
        }

        activeFragment = selectedFragment;
    }

如果在片段中更改工具栏,则无法正常工作。屏幕旋转后,工具栏菜单会重叠。 - Neuron

0
只需在onCreate方法中添加如下空实现即可: bottomNavView.setOnNavigationItemReselectedListener {}

0

我的完整解决方案,我认为对初学者会很有用:

所以,我们有一个MainActivity:

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment

class MainMenuActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_main)

  val bottomNav: BottomNavigationView = findViewById(R.id.bottom_naviagtion)
  bottomNav.setOnNavigationItemSelectedListener(navListener)

    if (savedInstanceState == null) {
         supportFragmentManager.beginTransaction().replace(
              R.id.fragment_container,
             HomeFragment()
         ).commit()
     }
 }

 private val navListener: BottomNavigationView.OnNavigationItemSelectedListener =
      BottomNavigationView.OnNavigationItemSelectedListener { item ->
         var selectedFragment: Fragment? = null
         when (item.itemId) {
        R.id.bottom_home -> selectedFragment =
            HomeFragment()
        R.id.bottom_events -> selectedFragment =
            EventFragment()
        R.id.bottom_contacts -> selectedFragment =
            ContactsFragment()
        R.id.bottom_menu -> selectedFragment =
            MenuFragment()
    }
    supportFragmentManager.beginTransaction().replace(
        R.id.fragment_container,
        selectedFragment!!
     ).commit()
     true
 }
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<FrameLayout
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@id/bottom_naviagtion"/>

<View
    android:layout_width="match_parent"
    android:layout_height="10dp"
    android:layout_above="@id/bottom_naviagtion"
    android:background="@drawable/shadow"/>

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/bottom_naviagtion"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    app:menu="@menu/bottom_menu"
    android:background="?android:attr/windowBackground" />

</RelativeLayout>

每个片段类看起来像这样:

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment

class HomeFragment : Fragment() {
   override fun onCreateView(
       inflater: LayoutInflater,
       container: ViewGroup?,
       savedInstanceState: Bundle?
   ): View? {
       return inflater.inflate(R.layout.fragment_home, container, false)
   }
 }

HomeFragment(fragment_home.xml)的.xml文件如下(其他片段看起来相同):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/home"
    android:textSize="30sp"
    android:layout_centerInParent="true"/>

</RelativeLayout>

NavigationBottomMenu.xml 的外观(bottom_menu.xml):

<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">

<item
    android:id="@+id/bottom_home"
    android:icon="@drawable/home_selector"
    android:title="Home" />


<item
    android:id="@+id/bottom_events"
    android:icon="@drawable/events_selector"
    android:title="Events" />

<item
    android:id="@+id/bottom_contacts"
    android:icon="@drawable/contacts_selector"
    android:title="Contacts"/>

<item
    android:id="@+id/bottom_menu"
    android:icon="@drawable/menu_selector"
    android:title="Menu" />

</menu>

从drawable文件夹中使用的图标被导入为矢量资源


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接