我正在关注android导航抽屉指南,一切顺利,直到我尝试创建导航抽屉基础活动,因此我可以扩展该活动并在所有活动中使用菜单。不幸的是我的应用程序一直在崩溃。
任何人都可以告诉我问题是什么,或者有人可以指出我正确的方向吗?
这是我的基本活动:
public class BaseActivity extends Activity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mPlanetTitles;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTitle = mDrawerTitle = getTitle();
mPlanetTitles = getResources().getStringArray(R.array.planets_array);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
mDrawerList = (ListView) findViewById(R.id.left_drawer1);
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, mPlanetTitles));
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
// enable ActionBar app icon to behave as action to toggle nav drawer
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
if (savedInstanceState == null) {
selectItem(0);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
/* Called whenever we call invalidateOptionsMenu() */
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// If the nav drawer is open, hide action items related to the content view
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this.
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle action buttons
switch(item.getItemId()) {
case R.id.action_websearch:
// create intent to perform web search for this planet
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY, getActionBar().getTitle());
// catch event that there's no activity to handle intent
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
} else {
Toast.makeText(this, R.string.app_not_available, Toast.LENGTH_LONG).show();
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/* The click listner for ListView in the navigation drawer */
private class DrawerItemClickListener implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
private void selectItem(int position) {
// update the main content by replacing fragments
Fragment fragment = new PlanetFragment();
Bundle args = new Bundle();
args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
fragment.setArguments(args);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(mPlanetTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
@Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
/**
* When using the ActionBarDrawerToggle, you must call it during
* onPostCreate() and onConfigurationChanged()...
*/
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggls
mDrawerToggle.onConfigurationChanged(newConfig);
}
/**
* Fragment that appears in the "content_frame", shows a planet
*/
public static class PlanetFragment extends Fragment {
public static final String ARG_PLANET_NUMBER = "planet_number";
public PlanetFragment() {
// Empty constructor required for fragment subclasses
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_planet, container, false);
int i = getArguments().getInt(ARG_PLANET_NUMBER);
String planet = getResources().getStringArray(R.array.planets_array)[i];
int imageId = getResources().getIdentifier(planet.toLowerCase(Locale.getDefault()),
"drawable", getActivity().getPackageName());
((ImageView) rootView.findViewById(R.id.image)).setImageResource(imageId);
getActivity().setTitle(planet);
return rootView;
}
}
}
这是应扩展BaseActivity的About.java:
public class About extends BaseActivity {
/** Called when the activity is first created. */
TextView a_text1,a_text2,a_text3;
ImageView a_img1, a_img2,a_img3;
String about1 = "Svojim kapacitetima i sa zaposlenima Sajam je osposobljen da zainteresovanim poslovnim partnerima pruži najraznovrsnije usluge.\nBeogradski sajam ima zatvoreni i otvoreni izložbeni prostor. Četrnaest hala Beogradskog sajma poseduje 100.000 kvadratnih metara izložbenog prostora. Centralna hala (Hala 1) je monumentalna građevina sa kupolom, ukupne površine 21.280m2. Svojom veličinomizdvajaju se još Hala 2 (9.239m2), Hala 3 (4.438m2) i Hala 14 (11.665m2) izložbene površine.\nUkupna površina otvorenog izložbenog prostora je 35.363m2";
String about2 = "Beogradski sajam raspolaže i poslovnim prostorom, magacinima i radionicama. Na Sajmu funkcionišu prateći sadržaji: pošta, banka, turističke agencije, špediterske službe, carinska služba i ambulanta. Takođe, u okviru Sajma rade i ugostiteljski objekti različite namene.\n\nNa Beogradskom sajmu se održi godišnje više od 30 redovnih međunarodnih sajamskih manifestacija. Sajmovi se odlikuju visokim nivoom organizacije te su mnoge priredbe učlanjene u ugledne međunarodne organizacije: Međunarodni sajam tehnike i tehničkih dostignuća, Međunarodni sajam odevanja - Moda u svetu, Međunarodni sajam nameštaja, opreme i unutrašnje dekoracije i Međunarodni sajam građevinarstva članovi su Međunarodne unije sajmova (UFI, Pariz).\n\nMeđunarodni salon automobila je jedan od zvaničnih registrovanih centara za izlaganje proizvoda automobilske industrije od strane Stalnog biroa proizvođača motornih vozila (OICA, Pariz).";
String about3 = "Pored redovnih manifestacija pod kupolama Beogradskog sajma održavaju se brojne izložbe, koncerti, naučni i specijalizovani skupovi. Ukupna ponuda Beogradskog sajma dopunjuje se bazarom robe široke potrošnje. Na Beogradskom sajmu godišnje izlaže oko 5000 kompanija, a obiđe ga preko 1.500.000 posetilaca. \n\nBeogradski sajam je od 2001. godine član i Centralnoevropske asocijacije sajmova (CEFA). \n\nOd septembra 2003. godine Medjunarodni sajam turizma član je Evropske asocijacije turističkih poslovnih sajmova (ITTFA).\nOd 2004.godine Beogradski sajam je član Asocijacije sajmova Jugoistočne Evrope (EASE).\nOd 1991. godine, Svetski trgovački centar Beograd član je Asocijacije svetskih trgovačkih centara (WTCA) sa sedištem u Njujorku. Povezuje najznačajnije tačke međunarodne trgovine u najsavremeniji komunikacijski sistem i omogućava kontakte sa poslovnim ljudima i firmama iz više od 330 gradova članica Asocijacije iz preko sto zemalja.\n\nBeogradski sajam je osnivač Svetskog trgovačkog centra Beograd (1991.)";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nav_drawer);
FrameLayout placeHolder = (FrameLayout) findViewById(R.id.frame);
getLayoutInflater().inflate(R.layout.about, placeHolder);
a_text1=(TextView)findViewById(R.id.a_text1);
a_text1.setText(about1);
a_text2=(TextView)findViewById(R.id.a_text2);
a_text2.setText(about2);
a_text3=(TextView)findViewById(R.id.a_text3);
a_text3.setText(about3);
}
}
这是我的nav_drawer.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<FrameLayout
android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer -->
<ListView android:id="@+id/left_drawer1"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
logcat的
05-07 21:34:58.106: I/ActivityManager(290): START u0 {cmp=com.example.android.navigationdrawerexample/.About} from pid 800
05-07 21:34:58.126: W/WindowManager(290): Failure taking screenshot for (246x410) to layer 21010
05-07 21:34:58.268: D/AndroidRuntime(800): Shutting down VM
05-07 21:34:58.286: W/dalvikvm(800): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
05-07 21:34:58.456: E/AndroidRuntime(800): FATAL EXCEPTION: main
05-07 21:34:58.456: E/AndroidRuntime(800): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.navigationdrawerexample/com.example.android.navigationdrawerexample.About}: java.lang.NullPointerException
05-07 21:34:58.456: E/AndroidRuntime(800): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
05-07 21:34:58.456: E/AndroidRuntime(800): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
05-07 21:34:58.456: E/AndroidRuntime(800): at android.app.ActivityThread.access$600(ActivityThread.java:141)
05-07 21:34:58.456: E/AndroidRuntime(800): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
05-07 21:34:58.456: E/AndroidRuntime(800): at android.os.Handler.dispatchMessage(Handler.java:99)
05-07 21:34:58.456: E/AndroidRuntime(800): at android.os.Looper.loop(Looper.java:137)
05-07 21:34:58.456: E/AndroidRuntime(800): at android.app.ActivityThread.main(ActivityThread.java:5041)
05-07 21:34:58.456: E/AndroidRuntime(800): at java.lang.reflect.Method.invokeNative(Native Method)
05-07 21:34:58.456: E/AndroidRuntime(800): at java.lang.reflect.Method.invoke(Method.java:511)
05-07 21:34:58.456: E/AndroidRuntime(800): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
05-07 21:34:58.456: E/AndroidRuntime(800): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
05-07 21:34:58.456: E/AndroidRuntime(800): at dalvik.system.NativeStart.main(Native Method)
05-07 21:34:58.456: E/AndroidRuntime(800): Caused by: java.lang.NullPointerException
05-07 21:34:58.456: E/AndroidRuntime(800): at com.example.android.navigationdrawerexample.BaseActivity.onCreate(BaseActivity.java:48)
05-07 21:34:58.456: E/AndroidRuntime(800): at com.example.android.navigationdrawerexample.About.onCreate(About.java:23)
05-07 21:34:58.456: E/AndroidRuntime(800): at android.app.Activity.performCreate(Activity.java:5104)
05-07 21:34:58.456: E/AndroidRuntime(800): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
05-07 21:34:58.456: E/AndroidRuntime(800): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
05-07 21:34:58.456: E/AndroidRuntime(800): ... 11 more
05-07 21:34:58.616: W/ActivityManager(290): Force finishing activity com.example.android.navigationdrawerexample/.About
05-07 21:34:58.646: W/ActivityManager(290): Force finishing activity com.example.android.navigationdrawerexample/.MainActivity
05-07 21:34:59.156: W/ActivityManager(290): Activity pause timeout for ActivityRecord{40efad28 u0 com.example.android.navigationdrawerexample/.About}
05-07 21:34:59.486: I/Choreographer(290): Skipped 78 frames! The application may be doing too much work on its main thread.
05-07 21:34:59.536: E/SurfaceFlinger(36): ro.sf.lcd_density must be defined as a build property
05-07 21:34:59.546: I/Choreographer(412): Skipped 75 frames! The application may be doing too much work on its main thread.
05-07 21:34:59.978: E/SurfaceFlinger(36): ro.sf.lcd_density must be defined as a build property
05-07 21:35:12.816: W/ActivityManager(290): Activity destroy timeout for ActivityRecord{40f16b00 u0 com.example.android.navigationdrawerexample/.MainActivity}
05-07 21:35:12.836: W/ActivityManager(290): Activity destroy timeout for ActivityRecord{40efad28 u0 com.example.android.navigationdrawerexample/.About}
如果有什么显而易见的事我明白了,请告诉我,因为我对应用开发社区很新。
任何帮助都会得到极大的赞赏。
谢谢! :)
答案 0 :(得分:1)
每DrawerLayout
只应有一个Application
。它的工作方式是你应该根据抽屉列表上的选择来替换Fragments
。 DrawerLayout
旨在作为一个集中组件,以便轻松访问View
中的深层Application
层次结构。例如,如果用户通过3个屏幕进入“配置文件”页面,则可以在抽屉中将其添加为项目时提供更好的体验。
答案 1 :(得分:0)
我建议采用与尝试创建使用导航抽屉的多个活动不同的路线。 Android有可用的片段,这是android似乎走向的方式。因此,您应该使用多个片段并在需要时切换片段,而不是使用多个活动。
这个链接是启动导航抽屉的好方法。 https://developer.android.com/training/implementing-navigation/nav-drawer.html
之后,您将只处理抽屉选择并用下一个片段替换主活动中的片段。
您将使用
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();
当您想要切换片段时。