如何在Navigation Drawer Activity中用自定义布局替代自动生成布局
你遇到的问题核心在于:系统自动生成的activity_student_home2是导航抽屉的完整容器结构,包含了导航抽屉必需的DrawerLayout、NavigationView以及工具栏框架;而你自己创建的activity_student_home只是一个简单的RelativeLayout,缺少这些核心组件,所以替换后导航抽屉逻辑找不到依赖的控件,自然失效,同时showtext的空指针也是因为原来的布局结构不匹配导致控件找不到。
下面给你两种可行的解决方案,你可以根据自己的需求选择:
方案一:直接修改你的activity_student_home为完整导航抽屉结构
把你的自定义内容直接集成到导航抽屉的标准布局结构中,这样既保留你的UI,又能让导航抽屉正常工作。
修改后的activity_student_home.xml代码:
<?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:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <!-- 主内容区域:包含工具栏和你的自定义UI --> <android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/app_back" tools:context="bd.edu.bubt.regup.StudentHomeActivity"> <!-- 顶部工具栏 --> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" /> </android.support.design.widget.AppBarLayout> <!-- 你的自定义内容 --> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <LinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerHorizontal="true" android:layout_centerVertical="false" android:layout_marginLeft="60dp" android:orientation="vertical"> <TextView android:id="@+id/showtext" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="300dp" android:gravity="center" android:text="Demo" android:textSize="24dp" android:textStyle="bold" /> </LinearLayout> </RelativeLayout> </android.support.design.widget.CoordinatorLayout> <!-- 侧滑导航视图 --> <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header_student_home" app:menu="@menu/activity_student_home2_drawer" /> </android.support.v4.widget.DrawerLayout>
然后修改StudentHomeActivity.java中的布局引用:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_student_home); // 替换为你的布局 showtext = findViewById(R.id.showtext); // 现在能正常找到控件了 showtext.setText("Registration is open"); // 以下导航抽屉的初始化逻辑保持不变 Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); 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); }
方案二:复用系统生成的布局组件(更易维护)
如果你想保留系统生成的app_bar_student_home和content_student_home结构,可以把你的自定义内容放到content_student_home中,然后让activity_student_home作为导航抽屉的容器。
- 修改
activity_student_home.xml为导航抽屉容器:
<?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:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <include layout="@layout/app_bar_student_home" android:layout_width="match_parent" android:layout_height="match_parent" /> <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header_student_home" app:menu="@menu/activity_student_home2_drawer" /> </android.support.v4.widget.DrawerLayout>
- 修改
content_student_home.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" 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="bd.edu.bubt.regup.StudentHomeActivity" tools:showIn="@layout/app_bar_student_home"> <LinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerHorizontal="true" android:layout_centerVertical="false" android:layout_marginLeft="60dp" android:orientation="vertical"> <TextView android:id="@+id/showtext" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="300dp" android:gravity="center" android:text="Demo" android:textSize="24dp" android:textStyle="bold" /> </LinearLayout> </RelativeLayout>
- 最后同样修改
StudentHomeActivity的setContentView为R.layout.activity_student_home即可。
关键说明
- 导航抽屉必须依赖
DrawerLayout作为根布局,它需要同时包含主内容区域和侧滑的NavigationView两个部分,缺少任何一个都会导致导航抽屉失效。 - 之前的空指针异常是因为你在使用
activity_student_home2时,showtext并不在它的布局结构里(它的主内容是content_student_home),所以找不到控件。现在把控件放到正确的位置后,就能正常获取了。
内容的提问来源于stack exchange,提问作者Sajib
相关产品推荐
相关产品推荐

