我想定义一个我可以在整个应用程序中使用的导航抽屉。我按照所选答案的说明作为我的第一个方法:Same Navigation Drawer in different Activities
我做了一些修改,即从被覆盖的onCreateDrawer
内部调用onCreate
。我更新了后续活动以扩展DashboardActivity
("基本活动"来自示例)。当我启动第二个活动时,我得到一个空指针异常,抱怨当onCreateDrawer
尝试设置抽屉上听到的切换时导航UI不存在。
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
以下是基础(仪表板)和后续(日志训练)活动 - 请询问是否还有其他想要查看的代码。在Android Studio中创建新的Nav Drawer Activity
时,抽屉用户界面和相关活动的代码就是开箱即用的。
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);
}
}
答案 0 :(得分:0)
我认为您错过了drawer_layout
布局中标识为activity_log_workout
的抽屉。
为了使这种方法有效,您必须在所有应该有抽屉的活动布局中使用ID为drawer_layout
的DrawerLayout。
我也注意到你的代码特有的东西。在扩展DashboardActivity
的每个活动中,您首先设置setContentView(R.id.activity_dashboard)
,然后调用onCreateDrawer()
,然后您将更改内容视图并再次创建抽屉。我认为这是一种非常不理想的方法。
我建议你创建一个BaseDrawerActivity
类来封装抽屉创建和UI绑定逻辑。然后,您只需在需要抽屉的活动中进行扩展。你可以这样做:
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();
}