将方法参数复制到最终临时变量不起作用
copying method parameter to a final temp variable isn't working
所以我有一个初始化抽屉菜单的方法,它需要一个 Drawer
参数,我用它来初始化抽屉。现在我尝试在单击抽屉项目后调用此抽屉参数来关闭它,但它给了我这个:
Variable 'drawer' is accessed from within inner class, needs to be declare final
所以我尝试在参数旁边手动分配 final
,它在我初始化新抽屉的那一行给了我这个错误:
Cannot assign a value to final variable 'drawer'
因此,我让 IDE 自动修复第一个问题,它建议将 'drawer' 参数复制到最终的临时变量。一旦我这样做了,没有显示错误,但是当我 运行 应用程序崩溃时,它在我调用 drawer.close
的行上给我 NPE !!
那么现在如何解决这个问题..!
代码:
public void initDrawerMenu(Drawer drawer) {
final Drawer finalDrawer = drawer; // the auto fix
drawer = new DrawerBuilder()
.withActivity(this)
.withMultiSelect(false)
.withOnDrawerItemClickListener(new OnDrawerItemClickListener() {
@Override
public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
switch (position) {
case 0:
finalDrawer.closeDrawer(); // the finalDrawer = null hence causes NPE
startActivity(new Intent(getApplicationContext(), HomeActivity.class));
break;
}
return true;
}
})
.build();
}
我用过 DrawerLayout 和 NavigationView。希望这有帮助
public class MyActivity extends Activity implements OnNavigationItemSelectedListener{
private DrawerLayout drawer;
@Override
public void onCreate(Bundle savedInstanceState) {
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
}
@Override
public boolean onNavigationItemSelected(MenuItem item) {
//close the drawer
drawer.closeDrawers();
switch (item.getItemId()) {
case R.id.item:
//do something
break;
}
}
}
P.S -> 这里 R.id.item 是一个 MenuItem
你可以像这样将菜单设置到 NavigationView
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true" >
<android.support.design.widget.NavigationView
android:id="@+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/my_navigation_items" />
</android.support.v4.widget.DrawerLayout>
这可能是因为您在 initDrawerMenu
中的抽屉为空或在您的方法之外被取消。
如果你想初始化 Drawer,你需要将方法更改为 return Drawer,而不是将你的 Drawer 变量传递给你的方法。因此,initDrawerMenu
不依赖于抽屉变量。
根据您的代码,我认为您要做的是创建一个抽屉而不是从现有抽屉初始化它。因此,您最好更改方法名称并使用 return 来创建抽屉。像这样:
public Drawer initDrawerMenu() {
final Drawer drawer = new DrawerBuilder()
.withActivity(this)
.withMultiSelect(false)
.withOnDrawerItemClickListener(new OnDrawerItemClickListener() {
@Override
public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
switch (position) {
case 0:
drawer.closeDrawer();
startActivity(new Intent(getApplicationContext(), HomeActivity.class));
break;
}
return true;
}
})
.build();
return drawer;
}
您应该将方法名称更改为更具可读性,例如:
public Drawer createDrawerMenu() {
...
}
当你想使用它的时候,你只需要这样调用它:
Drawer drawer = createDrawerMenu();
所以我有一个初始化抽屉菜单的方法,它需要一个 Drawer
参数,我用它来初始化抽屉。现在我尝试在单击抽屉项目后调用此抽屉参数来关闭它,但它给了我这个:
Variable 'drawer' is accessed from within inner class, needs to be declare final
所以我尝试在参数旁边手动分配 final
,它在我初始化新抽屉的那一行给了我这个错误:
Cannot assign a value to final variable 'drawer'
因此,我让 IDE 自动修复第一个问题,它建议将 'drawer' 参数复制到最终的临时变量。一旦我这样做了,没有显示错误,但是当我 运行 应用程序崩溃时,它在我调用 drawer.close
的行上给我 NPE !!
那么现在如何解决这个问题..!
代码:
public void initDrawerMenu(Drawer drawer) {
final Drawer finalDrawer = drawer; // the auto fix
drawer = new DrawerBuilder()
.withActivity(this)
.withMultiSelect(false)
.withOnDrawerItemClickListener(new OnDrawerItemClickListener() {
@Override
public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
switch (position) {
case 0:
finalDrawer.closeDrawer(); // the finalDrawer = null hence causes NPE
startActivity(new Intent(getApplicationContext(), HomeActivity.class));
break;
}
return true;
}
})
.build();
}
我用过 DrawerLayout 和 NavigationView。希望这有帮助
public class MyActivity extends Activity implements OnNavigationItemSelectedListener{
private DrawerLayout drawer;
@Override
public void onCreate(Bundle savedInstanceState) {
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
}
@Override
public boolean onNavigationItemSelected(MenuItem item) {
//close the drawer
drawer.closeDrawers();
switch (item.getItemId()) {
case R.id.item:
//do something
break;
}
}
}
P.S -> 这里 R.id.item 是一个 MenuItem
你可以像这样将菜单设置到 NavigationView
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true" >
<android.support.design.widget.NavigationView
android:id="@+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/my_navigation_items" />
</android.support.v4.widget.DrawerLayout>
这可能是因为您在 initDrawerMenu
中的抽屉为空或在您的方法之外被取消。
如果你想初始化 Drawer,你需要将方法更改为 return Drawer,而不是将你的 Drawer 变量传递给你的方法。因此,initDrawerMenu
不依赖于抽屉变量。
根据您的代码,我认为您要做的是创建一个抽屉而不是从现有抽屉初始化它。因此,您最好更改方法名称并使用 return 来创建抽屉。像这样:
public Drawer initDrawerMenu() {
final Drawer drawer = new DrawerBuilder()
.withActivity(this)
.withMultiSelect(false)
.withOnDrawerItemClickListener(new OnDrawerItemClickListener() {
@Override
public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
switch (position) {
case 0:
drawer.closeDrawer();
startActivity(new Intent(getApplicationContext(), HomeActivity.class));
break;
}
return true;
}
})
.build();
return drawer;
}
您应该将方法名称更改为更具可读性,例如:
public Drawer createDrawerMenu() {
...
}
当你想使用它的时候,你只需要这样调用它:
Drawer drawer = createDrawerMenu();