如何在所有活动中添加导航抽屉

时间:2014-01-25 16:00:10

标签: java android navigation-drawer android-actionbar-compat instantiationexception

我的App中有一个navigation Drawer。现在我需要让所有activities出现抽屉。

我看到很多与此类似的问题。找到了解决方案https://stackoverflow.com/a/4922740/2781359

但我在我的App中尝试过它。然后它抛出一个Exception

所以帮助我正确的方向:)

感谢您的帮助...
logcat的

       01-25 22:35:14.062: E/AndroidRuntime(17091): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ControllerDroid.client/com.ControllerDroid.client.activity.ControlActivity}: java.lang.UnsupportedOperationException: addView(View, LayoutParams) is not supported in AdapterView
01-25 22:35:14.062: E/AndroidRuntime(17091):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2215)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2265)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at android.app.ActivityThread.access$800(ActivityThread.java:145)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1206)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at android.os.Handler.dispatchMessage(Handler.java:102)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at android.os.Looper.loop(Looper.java:136)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at android.app.ActivityThread.main(ActivityThread.java:5081)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at java.lang.reflect.Method.invokeNative(Native Method)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at java.lang.reflect.Method.invoke(Method.java:515)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:781)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at dalvik.system.NativeStart.main(Native Method)
01-25 22:35:14.062: E/AndroidRuntime(17091): Caused by: java.lang.UnsupportedOperationException: addView(View, LayoutParams) is not supported in AdapterView
01-25 22:35:14.062: E/AndroidRuntime(17091):    at android.widget.AdapterView.addView(AdapterView.java:478)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at android.view.LayoutInflater.inflate(LayoutInflater.java:500)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at com.ControllerDroid.client.activity.MainActivity.setContentView(MainActivity.java:37)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at com.ControllerDroid.client.activity.MainActivity.onCreate(MainActivity.java:56)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at com.ControllerDroid.client.activity.ControlActivity.onCreate(ControlActivity.java:62)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at android.app.Activity.performCreate(Activity.java:5231)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
01-25 22:35:14.062: E/AndroidRuntime(17091):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2169)
01-25 22:35:14.062: E/AndroidRuntime(17091):    ... 11 more

MainActivity.java

    public class MainActivity extends ActionBarActivity
{
    protected DrawerLayout fullLayout;
    protected ListView actContent;
    private ListView mDrawerList;
    private DrawerLayout mDrawer;
    private CustomActionBarDrawerToggle mDrawerToggle;
    private String[] menuItems;
    @Override
    public void setContentView(final int layoutResID)
    {
       fullLayout = (DrawerLayout)getLayoutInflater().inflate(R.layout.activity_main_drawer, null); // Your  base layout here
        ListView actContent = (ListView) fullLayout.findViewById(R.id.drawer);
        getLayoutInflater().inflate(layoutResID, actContent, true); // Setting    the    content  of layout your  provided  to the  act_content frame
        super.setContentView(fullLayout);
        // here you can get your drawer buttons and define how they should
        // behave and what must they do, so you won't be needing to repeat it in
        // every activity class
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                getSupportActionBar().setHomeButtonEnabled(true);


                // set a custom shadow that overlays the main content when the drawer
                // opens
                fullLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

                _initMenu();
                mDrawerToggle = new CustomActionBarDrawerToggle(this, fullLayout);
                fullLayout.setDrawerListener(mDrawerToggle);
    }


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

activity_main_drawer.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" >

    <!-- The main content view -->

    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".MainActivity" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/text_color"
            android:text="@string/drawer_text" />
    </RelativeLayout>

    <!-- The navigation drawer -->

    <ListView
        android:id="@+id/drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:cacheColorHint="#00000000" 
         android:background="@color/list_background"
        android:choiceMode="singleChoice"
        android:textAppearance="@android:style/TextAppearance.Medium"
         android:divider="@android:color/transparent"
        android:dividerHeight="0dp" />

</android.support.v4.widget.DrawerLayout>

2 个答案:

答案 0 :(得分:1)

您的MainActivityabstract,无法实例化。

如果您打算将其保持抽象,请从清单中删除其条目,并确保您没有尝试使用显式Intent进行实例化。

答案 1 :(得分:0)

您正在投射错误的布局ID

试试这个

public abstract class MainActivity extends ActionBarActivity
{
    protected DrawerLayout fullLayout;
    protected ListView actContent;
    private ListView mDrawerList;
    private CustomActionBarDrawerToggle mDrawerToggle;
    private String[] menuItems;
    @Override
    public void setContentView(final int layoutResID)
    {
       fullLayout = (DrawerLayout)getLayoutInflater().inflate(R.layout.activity_main_drawer, null); // Your  base layout here
        ListView actContent = (ListView) fullLayout.findViewById(R.id.drawer);
        getLayoutInflater().inflate(layoutResID, actContent, true); // Setting    the    content  of layout your  provided  to the  act_content frame
        super.setContentView(fullLayout);
        // here you can get your drawer buttons and define how they should
        // behave and what must they do, so you won't be needing to repeat it in
        // every activity class
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                getSupportActionBar().setHomeButtonEnabled(true);


                // set a custom shadow that overlays the main content when the drawer
                // opens
                fullLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

                _initMenu();
                mDrawerToggle = new CustomActionBarDrawerToggle(this, fullLayout);
                fullLayout.setDrawerListener(mDrawerToggle);
    }

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

编辑完整解决方案:

main_content.xml

<?xml version="1.0" encoding="utf-8"?>

<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
        android:id="@+id/act_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


    <RelativeLayout
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start">

        <ListView
            android:layout_below="@+id/drawer_list"
            android:layout_width="240dp"
            android:id="@+id/filters_list"
            android:layout_height="wrap_content"/>
    </RelativeLayout>       
</android.support.v4.widget.DrawerLayout>

BaseActivity

protected DrawerLayout fullLayout;
protected FrameLayout actContent;
private ActionBarDrawerToggle mDrawerToggle;
ListView mDrawerList;


@Override
public void setContentView(final int layoutResID) {


    fullLayout= (DrawerLayout) getLayoutInflater().inflate(R.layout.main_content, null); // Your base layout here


    mDrawerList = (ListView)fullLayout.findViewById(R.id.drawer_list);
    fullLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED,mFilterList);
    fullLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

    int drawer_icon = R.drawable.ic_drawer;   
    mDrawerToggle = new ActionBarDrawerToggle(
            this,
            fullLayout,
           drawer_icon,
            R.string.drawer_open,
         R.string.drawer_close
        ) {
        public void onDrawerClosed(View view) {
            invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }

        public void onDrawerOpened(View drawerView) {
            invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }
    };
    fullLayout.setDrawerListener(mDrawerToggle);

    actContent= (FrameLayout) fullLayout.findViewById(R.id.act_content);
    getLayoutInflater().inflate(layoutResID, actContent, true); // Setting the content of layout your provided to the act_content frame

    super.setContentView(fullLayout);
}

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    mDrawerToggle.syncState();
}

由于