Navigation Drawer切换Fragment求助:替换初始Google Map Fragment
嘿,你已经把导航抽屉和谷歌地图的基础框架搭好了,现在就差实现Fragment切换的逻辑啦,别担心,这几步就能搞定:
第一步:把固定的Map Fragment改成可替换的容器
你现在的content_nav.xml里直接写了静态的SupportMapFragment,没法动态替换,我们得换成FrameLayout作为Fragment的容器:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout 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" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context=".NavActivity" tools:showIn="@layout/app_bar_nav"> <!-- 用FrameLayout作为Fragment的容器,替换原来的静态map fragment --> <FrameLayout android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent"/> </android.support.constraint.ConstraintLayout>
第二步:在onCreate中初始加载Map Fragment
现在xml里没有默认的Map Fragment了,我们要在onCreate里动态把它加载到容器中:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_nav); mAuth = FirebaseAuth.getInstance(); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); FloatingActionButton fab = findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); DrawerLayout drawer = findViewById(R.id.drawer_layout); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawer.addDrawerListener(toggle); toggle.syncState(); NavigationView navigationView = findViewById(R.id.nav_view); navigationView.setNavigationItemSelectedListener(this); navigationView.setCheckedItem(R.id.nav_home); /*Update the UI with user info*/ FirebaseUser user = mAuth.getCurrentUser(); TextView email = navigationView.getHeaderView(0).findViewById(R.id.navEmail); email.setText(user.getEmail()); TextView name = navigationView.getHeaderView(0).findViewById(R.id.navUsername); name.setText(user.getDisplayName()); // 初始加载Map Fragment到容器中,避免配置变化重复加载 if (savedInstanceState == null) { SupportMapFragment mapFragment = new SupportMapFragment(); getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_container, mapFragment) .commit(); mapFragment.getMapAsync(this); } }
第三步:完善onNavigationItemSelected的切换逻辑
现在你可以在每个菜单选项的分支里,创建对应的Fragment实例,然后替换容器里的内容。假设你已经有了ProfileFragment、SlideshowFragment这些自定义Fragment,代码可以这么写:
@SuppressWarnings("StatementWithEmptyBody") @Override public boolean onNavigationItemSelected(MenuItem item) { int id = item.getItemId(); Fragment selectedFragment = null; if (id == R.id.nav_home) { // 回到地图Fragment selectedFragment = new SupportMapFragment(); ((SupportMapFragment)selectedFragment).getMapAsync(this); } else if (id == R.id.nav_profile) { // 替换成个人资料Fragment selectedFragment = new ProfileFragment(); } else if (id == R.id.nav_slideshow) { // 替换成幻灯片Fragment selectedFragment = new SlideshowFragment(); } else if (id == R.id.nav_tools) { // 替换成工具Fragment selectedFragment = new ToolsFragment(); } else if (id == R.id.nav_share) { // 处理分享逻辑,不需要Fragment的话直接提示即可 Snackbar.make(findViewById(R.id.fragment_container), "分享功能待实现", Snackbar.LENGTH_SHORT).show(); } else if (id == R.id.nav_logout) { mAuth.signOut(); SharedPreferences sp = getSharedPreferences("Login", MODE_PRIVATE); SharedPreferences.Editor Ed = sp.edit(); Ed.putString("Email", null); Ed.putString("Password", null); Ed.apply(); Intent intent = new Intent(getApplicationContext(), MainActivity.class); startActivity(intent); finish(); // 退出当前页面,避免返回 } // 如果有选中的Fragment,执行替换操作 if (selectedFragment != null) { getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_container, selectedFragment) .commit(); } DrawerLayout drawer = findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); return true; }
一些小提示
- 记得提前创建好对应的自定义Fragment类(比如
ProfileFragment),不然代码会报错哦。 - 如果想给Fragment切换加动画,可以在
beginTransaction()之后加上setCustomAnimations()方法,比如setCustomAnimations(R.anim.fade_in, R.anim.fade_out)。 - 对于不需要Fragment的菜单选项,直接处理业务逻辑即可,不用赋值
selectedFragment。
内容的提问来源于stack exchange,提问作者Denis
相关产品推荐
相关产品推荐

