Android Fragment导航问题:Tabs显示异常与FAB显示控制
Let's tackle your two Fragment navigation problems one by one, with clear explanations and actionable code changes:
Issue 1: TabLayout from First Fragment Remains Visible When Navigating to Second Fragment
Root Cause
Your current layout structure has the TabLayout and ViewPager directly embedded in the Activity's layout, not as part of the HomeFragment. That means when you switch to ProfileFragment via the navigation drawer, these UI elements stay on screen because they belong to the Activity, not the Fragment being replaced.
Step-by-Step Fix
- Rewrite
activity_homepage.xmlto remove TabLayout and ViewPager, keeping only the essential container structure:
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout 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" android:id="@+id/drawer_layout" android:fitsSystemWindows="true" tools:context=".Activities.Homepage" android:background="#000000" tools:openDrawer="start"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v7.widget.Toolbar android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/common_google_signin_btn_text_dark_focused" android:id="@+id/toolbar" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Dark" android:elevation="4dp"/> <!-- Only keep the fragment container; move tabs/viewpager to HomeFragment's layout --> <FrameLayout android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout> <android.support.design.widget.NavigationView android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:id="@+id/nav_view" app:headerLayout="@layout/nav_header" app:menu="@menu/drawer_menu"/> </android.support.v4.widget.DrawerLayout>
- Create
fragment_home.xmlforHomeFragment, moving the TabLayout and ViewPager here:
<?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" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.design.widget.TabLayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/colorPrimary" /> <android.support.v4.view.ViewPager android:id="@+id/viewpagers" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
- Update
HomeFragment.javato initialize TabLayout and ViewPager inside the Fragment:
public class HomeFragment extends Fragment { private static final String TAG = "HomeFragment"; private SectionsPageAdapter mSectionsPageAdapter; private ViewPager mViewPager; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_home, container, false); // Set up ViewPager and TabLayout within the fragment mSectionsPageAdapter = new SectionsPageAdapter(getChildFragmentManager()); mViewPager = view.findViewById(R.id.viewpagers); setupViewPager(mViewPager); TabLayout tabLayout = view.findViewById(R.id.tabs); tabLayout.setupWithViewPager(mViewPager); return view; } private void setupViewPager(ViewPager viewPager) { SectionsPageAdapter adapter = new SectionsPageAdapter(getChildFragmentManager()); adapter.addFragment(new FragmentPopular(), "Popular"); adapter.addFragment(new FragmentUpcoming(), "Upcoming"); viewPager.setAdapter(adapter); } }
- Clean up
Homepage.javaby removing Activity-level ViewPager/TabLayout initialization:
public class Homepage extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { private static final String TAG = "Homepage"; private DrawerLayout drawer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_homepage); Toolbar toolbar = findViewById(R.id.toolbar); drawer = findViewById(R.id.drawer_layout); NavigationView navigationview = findViewById(R.id.nav_view); navigationview.setNavigationItemSelectedListener(this); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawer.addDrawerListener(toggle); toggle.syncState(); if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_container, new HomeFragment()) .commit(); navigationview.setCheckedItem(R.id.nav_home); } } @Override public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { Fragment fragment = null; switch (menuItem.getItemId()) { case R.id.nav_home: fragment = new HomeFragment(); break; case R.id.nav_profile: fragment = new ProfileFragment(); break; case R.id.nav_discussion: fragment = new DiscussionFragment(); break; } if (fragment != null) { getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_container, fragment) .commit(); } drawer.closeDrawer(GravityCompat.START); return true; } @Override public void onBackPressed() { if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START); } else { super.onBackPressed(); } } }
Now when you navigate to ProfileFragment, HomeFragment (and its TabLayout/ViewPager) will be completely replaced, so the tabs won't stay visible.
Issue 2: Hide FAB for the Second Fragment
Solution
Assuming your FAB is in the Activity's layout (if it's in HomeFragment, it will hide automatically when the fragment is replaced), we can toggle its visibility when navigating between fragments.
- Add FAB to
activity_homepage.xml(if you haven't already):
<!-- Insert this inside the main LinearLayout, after the fragment container --> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="16dp" app:srcCompat="@drawable/ic_add"/>
- Update
Homepage.javato control FAB visibility:
public class Homepage extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { private static final String TAG = "Homepage"; private DrawerLayout drawer; private FloatingActionButton fab; // Add reference to FAB @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_homepage); Toolbar toolbar = findViewById(R.id.toolbar); drawer = findViewById(R.id.drawer_layout); fab = findViewById(R.id.fab); // Initialize FAB NavigationView navigationview = findViewById(R.id.nav_view); navigationview.setNavigationItemSelectedListener(this); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawer.addDrawerListener(toggle); toggle.syncState(); // Show FAB by default (since we start on HomeFragment) fab.show(); if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_container, new HomeFragment()) .commit(); navigationview.setCheckedItem(R.id.nav_home); } } @Override public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { Fragment fragment = null; boolean showFab = true; switch (menuItem.getItemId()) { case R.id.nav_home: fragment = new HomeFragment(); showFab = true; break; case R.id.nav_profile: fragment = new ProfileFragment(); showFab = false; // Hide FAB for ProfileFragment break; case R.id.nav_discussion: fragment = new DiscussionFragment(); showFab = false; // Adjust based on your needs break; } if (fragment != null) { getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_container, fragment) .commit(); } // Toggle FAB visibility if (showFab) { fab.show(); } else { fab.hide(); } drawer.closeDrawer(GravityCompat.START); return true; } // ... Rest of the code remains the same }
This will hide the FAB whenever you navigate to ProfileFragment or DiscussionFragment, and show it when you return to HomeFragment.
内容的提问来源于stack exchange,提问作者Kyprius

