在 BottomNavigationView 中的片段之间切换
Switch between Fragments in BottomNavigationView
我正在使用带有底部导航视图的简单应用程序。我有 3 个片段(布局和 java)。我有 BottonNavigationView,在我的 MainActivity.java 中声明。我的 bottonnavigation 有 3 个项目,用于 3 个片段。所以,在我的 MainActivity.java 中,当我 select 一个项目时,它开始一个片段。因此,当我再次 select 另一个项目时,没有任何反应,因为在 java 片段中我需要声明 BottonNavigationView,但我不知道如何设置它以将实际片段与另一个片段切换.
我尝试了这个 link,但没有成功:https://developer.android.com/training/basics/fragments/fragment-ui.html
抱歉我的英语不好
这里是代码:
主要Activity
@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);
}
你可以试试:
@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;
}
在这种情况下,最好尝试从 fragmentManager
中获取现有片段,例如 fragmentManager.findFragmentByTag(tag)
。您可以更顺畅地切换,并且您不需要例如从网络加载一些内容(如果您在片段或片段的演示者中有这样的代码)
您不必每次都创建 newInstance。您可以保存片段状态。按照下面的link
fragmentManager.beginTransaction().hide(toBeHidden).show(toBeShown).commit();
https://medium.com/@oluwabukunmi.aluko/bottom-navigation-view-with-fragments-a074bfd08711
您应该从每个片段创建一次 newIstance。稍后您可以隐藏活动片段,然后显示新片段。
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;
}
只是在onCreate中添加一个这样的空白实现
bottomNavView.setOnNavigationItemReselectedListener{}
我的完整解决方案,我认为对后辈有用:
所以,我们有 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>
每个片段 class 看起来像:
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)
}
}
.xml HomeFragment (fragment_home.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>
drawble 文件夹中使用的图标像 Vector Asset 一样导入
我正在使用带有底部导航视图的简单应用程序。我有 3 个片段(布局和 java)。我有 BottonNavigationView,在我的 MainActivity.java 中声明。我的 bottonnavigation 有 3 个项目,用于 3 个片段。所以,在我的 MainActivity.java 中,当我 select 一个项目时,它开始一个片段。因此,当我再次 select 另一个项目时,没有任何反应,因为在 java 片段中我需要声明 BottonNavigationView,但我不知道如何设置它以将实际片段与另一个片段切换. 我尝试了这个 link,但没有成功:https://developer.android.com/training/basics/fragments/fragment-ui.html
抱歉我的英语不好
这里是代码:
主要Activity
@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);
}
你可以试试:
@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;
}
在这种情况下,最好尝试从 fragmentManager
中获取现有片段,例如 fragmentManager.findFragmentByTag(tag)
。您可以更顺畅地切换,并且您不需要例如从网络加载一些内容(如果您在片段或片段的演示者中有这样的代码)
您不必每次都创建 newInstance。您可以保存片段状态。按照下面的link
fragmentManager.beginTransaction().hide(toBeHidden).show(toBeShown).commit();
https://medium.com/@oluwabukunmi.aluko/bottom-navigation-view-with-fragments-a074bfd08711
您应该从每个片段创建一次 newIstance。稍后您可以隐藏活动片段,然后显示新片段。
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;
}
只是在onCreate中添加一个这样的空白实现 bottomNavView.setOnNavigationItemReselectedListener{}
我的完整解决方案,我认为对后辈有用:
所以,我们有 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>
每个片段 class 看起来像:
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)
}
}
.xml HomeFragment (fragment_home.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>
drawble 文件夹中使用的图标像 Vector Asset 一样导入