如何在多个活动中使用导航抽屉 [英] How to use nav drawer in multiple activities
问题描述
我想定义一个可以在整个应用程序中使用的导航抽屉.我按照此处选择的答案的指示作为我的第一种方法:相同的导航抽屉在不同的位置活动
I want to define a single nav drawer I can use throughout my application. I followed the instructions of the chosen answer here as my first approach: Same Navigation Drawer in different Activities
我做了一些修改,即从覆盖的onCreate
内部调用onCreateDrawer
.我更新了我的后续活动以扩展DashboardActivity
(示例中的基本活动").当我启动第二个活动时,我得到一个空指针异常,抱怨当onCreateDrawer
尝试设置在抽屉上侦听的切换时,导航UI不存在.
I made a few modifications, namely calling onCreateDrawer
from inside an overridden onCreate
. I updated my subsequent activity to extend DashboardActivity
("base activity" from the example). When I launch my second activity I get a null pointer exception complaining that the nav UI doesn't exist when onCreateDrawer
tries to set the toggle listened on the drawer.
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.widget.DrawerLayout.setDrawerListener(android.support.v4.widget.DrawerLayout$DrawerListener)' on a null object reference
这是基础(仪表板)和后续(日志锻炼)活动-请询问是否还有其他代码想要查看.抽屉UI和相关活动的代码是在Android Studio中创建新的Nav Drawer Activity
时开箱即用的代码.
Here are the base (dashboard) and subsequent (log workout) activity - please ask if there is other code you want to see. The code for the UI of the drawer and associated activity are what came out of the box when creating a new Nav Drawer Activity
in Android Studio.
DashboardActivity.java
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
onCreateDrawer();
Realm realm = Realm.getDefaultInstance();
RealmQuery<Exercise> query = realm.where(Exercise.class);
RealmResults<Exercise> result = query.findAll();
Log.d(TAG, "There are " + result.size() + " exercises ready for use.");
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent logWorkoutIntent = new Intent(getApplicationContext(), LogWorkoutActivity.class);
startActivity(logWorkoutIntent);
}
});
//TODO: Remove this sign out button
Button signOutButton = (Button) findViewById(R.id.button_sign_out);
signOutButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FirebaseAuth.getInstance().signOut();
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
startActivity(intent);
Toast.makeText(getApplicationContext(), "Signed out", Toast.LENGTH_LONG).show();
}
});
//TODO: Remove this data tester
updateUserName();
}
//@Override
protected void onCreateDrawer() {
Log.d(TAG, "onCreateDrawer called");
//super.onCreate(savedInstanceState);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, mDrawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
mDrawerLayout.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
...
-
LogWorkoutActivity.java
public class LogWorkoutActivity extends DashboardActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_log_workout);
setContentView(R.layout.activity_log_workout);
super.onCreateDrawer();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) 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();
}
});
//getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
}
推荐答案
我认为您在activity_log_workout
布局中缺少ID为drawer_layout
的抽屉.
I think you are missing a drawer with id drawer_layout
in your activity_log_workout
layout.
为使此方法起作用,必须在所有应具有抽屉的活动布局中使用ID为drawer_layout
的DrawerLayout.
In order for this approach to work, you must have a DrawerLayout with id drawer_layout
in all your activity layouts that should have the drawer.
我还注意到您的代码有一些特殊之处.在扩展DashboardActivity
的每个活动中,您首先要设置setContentView(R.id.activity_dashboard)
,然后调用onCreateDrawer()
,然后更改内容视图并再次创建抽屉.我认为这是一种非常不理想的方法.
I also noticed something peculiar with your code. In every activity that extends DashboardActivity
you are first setting setContentView(R.id.activity_dashboard)
, then calling onCreateDrawer()
, then you are changing the content view and creating the drawer again. I think this a very suboptimal approach.
我建议您创建一个BaseDrawerActivity
类来封装抽屉创建和UI绑定逻辑.然后,将其扩展到需要抽屉的活动中.您可以这样做:
I suggest you create a BaseDrawerActivity
class to encapsulate the drawer creation and UI binding logic. Then you just extend it in the activities where you need a drawer. You can do it like this:
public abstract class BaseDrawerActivity extends AppCompatActivity {
// move all your drawer related fields here
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate();
setContentView(getLayoutResId());
// the same method you have right now
onCreateDrawer();
}
/*
* Extending activities use this class to supply the
* id of their layout file. This way you can set the view
* only once and there is no need to create the drawer twice.
*/
@LayoutResId
public abstract int getLayoutResId();
}
这篇关于如何在多个活动中使用导航抽屉的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!