0
votes

I'm making my own navigation-drawer by adapting the "sample app" code at http://developer.android.com/training/implementing-navigation/nav-drawer.html

I don't want to use fragments. I simply want to go to a new activity whenever i select an option in the drawer. The thing is, when i remove the FrameLayout from my activity_main.xml i get a NullPointerException but if i don't remove it i don't get the exception... I don't understand why is this happening since i'm not using that FrameLayout anywhere.

Here's my MainActivity.

    public class MainActivity extends Activity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
// slide menu items
private String[] navMenuTitles;
private TypedArray navMenuIcons;

private ArrayList<NavDrawerItem> navDrawerItems;
private NavDrawerListAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // load slide menu items
    navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);

    // nav drawer icons from resources
    navMenuIcons = getResources()
            .obtainTypedArray(R.array.nav_drawer_icons);

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerList = (ListView) findViewById(R.id.list_slidermenu);

    navDrawerItems = new ArrayList<NavDrawerItem>();

    // adding nav drawer items to array
    // History
    navDrawerItems.add(new NavDrawerItem(navMenuTitles[0], navMenuIcons.getResourceId(0, -1)));
    // Contacts
    navDrawerItems.add(new NavDrawerItem(navMenuTitles[1], navMenuIcons.getResourceId(1, -1)));
    // Information
    navDrawerItems.add(new NavDrawerItem(navMenuTitles[2], navMenuIcons.getResourceId(2, -1)));
    // Check out
    navDrawerItems.add(new NavDrawerItem(navMenuTitles[3], navMenuIcons.getResourceId(3, -1)));


    // Recycle the typed array
    navMenuIcons.recycle();

    mDrawerList.setOnItemClickListener(new SlideMenuClickListener());

    // setting the nav drawer list adapter
    adapter = new NavDrawerListAdapter(getApplicationContext(),
            navDrawerItems);
    mDrawerList.setAdapter(adapter);

    // enabling action bar app icon and behaving it as toggle button
    getActionBar().setDisplayShowHomeEnabled(true);
    getActionBar().setDisplayHomeAsUpEnabled(true);

    mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
            R.drawable.ic_drawer, //nav menu toggle icon
            R.string.app_name, // nav drawer open - description for accessibility
            R.string.app_name // nav drawer close - description for accessibility
            ) {
        public void onDrawerClosed(View view) {
            getActionBar().setTitle(R.string.empty);
            // calling onPrepareOptionsMenu() to show action bar icons
            //              invalidateOptionsMenu();
        }

        public void onDrawerOpened(View drawerView) {
            getActionBar().setTitle(R.string.back_to_JobList);
            // calling onPrepareOptionsMenu() to hide action bar icons
            invalidateOptionsMenu();
        }
    };
    mDrawerLayout.setDrawerListener(mDrawerToggle);
}

/**
 * Slide menu item click listener
 * */
private class SlideMenuClickListener implements
ListView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {
        // display view for selected nav drawer item
        displayView(position);
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

public boolean onOptionsItemSelected(MenuItem item) {


    // toggle nav drawer on selecting action bar app icon/title
    if (mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    // Handle action bar actions click
    // Handle presses on the action bar items
    switch (item.getItemId()) {
    case R.id.map_view:
        Toast.makeText(getApplicationContext(), "Map view pressed",
                Toast.LENGTH_LONG).show();
        //startActivity(GoogleMapsActivity.class);
        return true;


    case R.id.infrastucture_only:
        Toast.makeText(getApplicationContext(),
                "Infrastucture only pressed", Toast.LENGTH_LONG).show();
        return true;
    case R.id.infrastucture_map:
        Toast.makeText(getApplicationContext(),
                "Infrastucture + map pressed", Toast.LENGTH_LONG).show();
        return true;
    case R.id.camera_only:
        Toast.makeText(getApplicationContext(), "Camera only pressed",
                Toast.LENGTH_LONG).show();
        return true;
    case R.id.camera_infrastucture:

        Toast.makeText(getApplicationContext(),
                "Infrastucture + Camera pressed", Toast.LENGTH_LONG).show();
        //startActivity(MetaioActivity.class);
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

/* *
 * Called when invalidateOptionsMenu() is triggered
 */
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    // if nav drawer is opened, hide the action items
    boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
    menu.findItem(R.id.dots_menu).setVisible(!drawerOpen);
    return super.onPrepareOptionsMenu(menu);
}

/**
 * Diplaying fragment view for selected nav drawer list item
 * */
private void displayView(int position) {

    switch (position) {
    case 0:
        Toast.makeText(getApplicationContext(),
                "History pressed", Toast.LENGTH_LONG).show();
        Intent intent = new Intent(this, Teste.class);
        startActivity(intent);
        break;

    case 1:
        Toast.makeText(getApplicationContext(),
                "Contacts pressed", Toast.LENGTH_LONG).show();
        break;

    case 2:
        Toast.makeText(getApplicationContext(),
                "Information pressed", Toast.LENGTH_LONG).show();
        break;

    case 3:
        Toast.makeText(getApplicationContext(),
                "Check out pressed", Toast.LENGTH_LONG).show();
        break;


    default:
        break;
    }       
}


/**
 * 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);
}

    }

Here's my activity_main.xml

<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">

  <!-- Framelayout to display Fragments -->
<FrameLayout
    android:id="@+id/frame_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<!-- Listview to display slider menu -->
<ListView
    android:id="@+id/list_slidermenu"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:choiceMode="singleChoice"
    android:divider="@color/list_divider"
    android:dividerHeight="1dp"        
    android:listSelector="@drawable/list_selector"
    android:background="@color/list_background"/>
 </android.support.v4.widget.DrawerLayout>

and finely, here's the log-cat output

03-03 15:00:07.317: E/Trace(810): error opening trace file: No such file or directory    (2)
03-03 15:00:08.058: I/Choreographer(810): Skipped 41 frames!  The application may be doing too much work on its main thread.
03-03 15:00:08.087: D/gralloc_goldfish(810): Emulator without GPU emulation detected.
03-03 15:00:10.867: E/InputEventReceiver(810): Exception dispatching input event.
03-03 15:00:10.867: E/MessageQueue-JNI(810): Exception in MessageQueue callback: handleReceiveCallback
03-03 15:00:10.938: E/MessageQueue-JNI(810): java.lang.NullPointerException
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at   android.support.v4.widget.DrawerLayout.isContentView(DrawerLayout.java:853)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.support.v4.widget.DrawerLayout.onInterceptTouchEvent(DrawerLayout.java:879)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1822)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1877)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1877)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1877)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1925)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1379)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.app.Activity.dispatchTouchEvent(Activity.java:2396)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1873)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.view.View.dispatchPointerEvent(View.java:7307)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3174)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3119)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4155)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4134)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4226)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.os.MessageQueue.nativePollOnce(Native Method)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.os.MessageQueue.next(MessageQueue.java:125)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.os.Looper.loop(Looper.java:124)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at android.app.ActivityThread.main(ActivityThread.java:4745)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at java.lang.reflect.Method.invokeNative(Native Method)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at java.lang.reflect.Method.invoke(Method.java:511)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-03 15:00:10.938: E/MessageQueue-JNI(810):    at dalvik.system.NativeStart.main(Native Method)
03-03 15:00:10.938: D/AndroidRuntime(810): Shutting down VM
03-03 15:00:10.938: W/dalvikvm(810): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
03-03 15:00:11.058: E/AndroidRuntime(810): FATAL EXCEPTION: main
03-03 15:00:11.058: E/AndroidRuntime(810): java.lang.NullPointerException
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.support.v4.widget.DrawerLayout.isContentView(DrawerLayout.java:853)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.support.v4.widget.DrawerLayout.onInterceptTouchEvent(DrawerLayout.java:879)
03-03 15:00:11.058: E/AndroidRuntime(810):  at    android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1822)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1877)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1877)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1877)
03-03 15:00:11.058: E/AndroidRuntime(810):  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.j ava:1925)
03-03 15:00:11.058: E/AndroidRuntime(810):  at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1379)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.app.Activity.dispatchTouchEvent(Activity.java:2396)
03-03 15:00:11.058: E/AndroidRuntime(810):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1873)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.view.View.dispatchPointerEvent(View.java:7307)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3174)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3119)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4155)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4134)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4226) 
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.os.MessageQueue.nativePollOnce(Native Method)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.os.MessageQueue.next(MessageQueue.java:125)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.os.Looper.loop(Looper.java:124)
03-03 15:00:11.058: E/AndroidRuntime(810):  at android.app.ActivityThread.main(ActivityThread.java:4745)
03-03 15:00:11.058: E/AndroidRuntime(810):  at java.lang.reflect.Method.invokeNative(Native Method)
03-03 15:00:11.058: E/AndroidRuntime(810):  at java.lang.reflect.Method.invoke(Method.java:511)
03-03 15:00:11.058: E/AndroidRuntime(810):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
03-03 15:00:11.058: E/AndroidRuntime(810):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-03 15:00:11.058: E/AndroidRuntime(810):  at dalvik.system.NativeStart.main(Native Method)
03-03 15:00:11.168: D/dalvikvm(810): GC_CONCURRENT freed 257K, 10% free 7438K/8199K, paused 74ms+16ms, total 207ms
03-03 15:05:11.188: I/Process(810): Sending signal. PID: 810 SIG: 9
2

2 Answers

1
votes

as stated in the link you attached:

To add a navigation drawer, declare your user interface with a DrawerLayout object as the root view of your layout. Inside the DrawerLayout, add one view that contains the main content for the screen (your primary layout when the drawer is hidden) and another view that contains the contents of the navigation drawer.

this meaning DrawerLayout expects to get 2 views - one is the primary view and the other the drawer. If you remove the FrameLayout you will need to add a dummy view instead.

0
votes

According to Android Doc about create an Navigation Drawer you need to create android.support.v4.widget.DrawerLayout as root for your layout with two Child views : FragmentLayout and ListView

because the XML order implies z-ordering and the drawer must be on top of the content.

if you don't need to use FragmentLayout view ,you can make it's visibility is gone

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

      <!-- Framelayout to display Fragments -->
    <FrameLayout
        android:id="@+id/frame_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone" />

    <!-- Listview to display slider menu -->
    <ListView
        android:id="@+id/list_slidermenu"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@color/list_divider"
        android:dividerHeight="1dp"        
        android:listSelector="@drawable/list_selector"
        android:background="@color/list_background"/>
</android.support.v4.widget.DrawerLayout>