我不知道如何使用findViewById(R.id.nav_timetable);
而不返回null并创建NPE。我尝试做的是默认加载TimetableFragment,然后人们可以使用抽屉转到其他片段。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setupDrawer(toolbar);
drawer.openDrawer(GravityCompat.START); // Opened this on first run so they know what's in it.
// TODO Change this later to a home page and remove goToTimetablePage();
// goToTimetablePage();
goToFragmentFromNavMenuItem((MenuItem) findViewById(R.id.nav_timetable));
}
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
// Handle navigation view item clicks here.
goToFragmentFromNavMenuItem(menuItem);
return true;
}
private void goToFragmentFromNavMenuItem(MenuItem menuItem) {
// Create a new fragment and specify the fragment to show based on nav item clicked
Fragment fragment = null;
Class fragmentClass;
switch (menuItem.getItemId()) {
case R.id.nav_slideshow: // TODO fragmentClass = SlideshowFragment.class; break;
case R.id.nav_share: // TODO fragmentClass = ShareFragment.class; break;
case R.id.nav_timetable:
fragmentClass = TimetableFragment.class;
// goToTimetablePage();
break;
default:
fragmentClass = TimetableFragment.class;
// TODO Change this later to a home page:
// TODO fragmentClass = HomeFragment.class; Remove "goToTimetablePage();"
}
//noinspection TryWithIdenticalCatches
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
menuItem.setChecked(true);
setTitle(menuItem.getTitle());
drawer.closeDrawer(GravityCompat.START);
}
错误讯息:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gmail.gogobebe2.thedayahead/com.gmail.gogobebe2.thedayahead.MainActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'int android.view.MenuItem.getItemId()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'int android.view.MenuItem.getItemId()' on a null object reference
at com.gmail.gogobebe2.thedayahead.MainActivity.goToNavFragment(MainActivity.java:123)
at com.gmail.gogobebe2.thedayahead.MainActivity.onCreate(MainActivity.java:59)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
我尝试使用onCreateView
方法,但由于某种原因它只是制作了stackoverflow消息。
编辑:这里是解决任何混淆的所有代码:https://github.com/gogobebe2/TheDayAhead
EDIT2:确保您不必担心goToTimetablePage()
方法。目前尚未使用,我计划将其移至TimetableFragment
片段。
EDIT3:我将方法名称更改为goToFragmentFromNavMenuItem()
,以便更好地描述其清除操作的操作。我还想让你们知道onNavigationItemSelected(MenuItem menuItem)
方法与goToFragmentFromNavMenuItem()
方法完美配合,只是因为它在onCreate(Bundle savedInstanceState)
内部使用时不起作用,因为findViewById(R.id.nav_timetable)
一直返回null
。
此外,这是我制作的第一款Android应用程序,我在学习时有点学习。我甚至不知道昨晚的片段是什么,所以我对Android很新,请不要承担任何知识。
答案 0 :(得分:1)
为了避免因 NPE 导致的崩溃,您可以在传递之前测试返回值是否为null:
MenuItem menuItem = (MenuItem) findViewById(R.id.nav_timetable);
if (menuItem != null) {
goToNavFragment(menuItem);
}
无论如何,这无法解决您的问题,实际上findViewById(int)
正在返回null
,因为您正在搜索的视图ID不存在于您的活动布局中。
方法findViewById()
,来自View
类,您在this
上调用它Activity
(一个扩展View的类) ,在当前膨胀的布局中搜索视图ID(来自R
)。
现在,如果您查看onCreate
实施内容,就会发现您正在调用setContentViewMethod(R.layout.activity_main)
;这意味着您需要设置此活动的布局,并将其从ID为activity_main
的xml布局中删除。
这里最大的问题是您传递的布局(activity_main
)不包含您正在寻找的ID。只需查看activity_main.xml
布局文件,因为您可以看到没有ID为R.id.nav_timetable
的对象。
活动一次只能加载一个布局活动文件。您仍然可以为菜单或特定视图对象(Spinner
s,List
等)加载其他布局文件。
最重要的是,您正在尝试检索MenuItem
;要实现这一目标,您必须覆盖两个方法onCreateOptionsMenu()
和onOptionsItemSelected()
。
<小时/>
onCreateOptionsMenu()
就像它的名字所说的那样。它会创建您将要使用的选项菜单。在这里你可以勾勒你的行动,但你必须做的最重要的事情是膨胀菜单布局。如果没有这个,您将无法应用自定义菜单布局并使用findViewById
。
因此,在调用findViewById()之前,你应该这样做:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.your_menu_id, menu);
// findViewById()
return true;
}
当您选择先前创建的菜单中的项目时,将调用onOptionsItemSelected()
,它将为您提供所选MenuItem
的参数,您可以在此处实现菜单项单击操作。标准实现可以如下:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_one:
doSomething()
return true;
case R.id.action_two:
doSomethingElse();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
答案 1 :(得分:0)
不返回null的方法是为视图传递一个有效的Id。查看您的xml设计文件,并在函数中使用id,如下所示:
rootview.findViewById(R.id.your_id_here)
答案 2 :(得分:0)
由于您的问题不包含布局文件,我认为R.id.nav_timetable
指的是片段的ID(并且它是您的一部分布局)?如果是,则需要使用findFragmentById()
(或FragmentManager
)中的SupportFragmentManager
代替findViewById()
。