使用导航抽屉扩展viewpager

时间:2014-12-25 21:59:34

标签: android navigation android-viewpager drawer

目前我有一个Base Activity类,它在我的所有活动中实现了一个操作栏,我现在想要添加到这个基类,以便它实现一个导航抽屉。但是,实现导航抽屉的基本活动会给我带来很多冲突的视图错误。

我的主要目标是让一个viewpager活动扩展这个实现导航抽屉的基本活动,我该怎么做?或者有工作吗?

由于

3 个答案:

答案 0 :(得分:0)

这就是我这样做的方式。我不记得我把它拿走了但是它也改变了。在我的例子中,我将其定义为抽象,并从中扩展了我的MainActivity。原因是将与DrawerActivity相关的逻辑保留在一个类中,因此它不会与我的业务逻辑混合。

public abstract class DrawerActivity extends BaseActivity {

    private ActionBarDrawerToggle mDrawerListener;
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ListAdapter mDrawerListAdapter;

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

        mDrawerList = (ListView) findViewById(R.id.drawer_list);

    }

    @Override
    public void onSupportContentChanged() {
        super.onSupportContentChanged();
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (mDrawerLayout == null) {
            throw new RuntimeException(
                    "Your layout must be a DrawerLayout"
            );
        }
        mDrawerList = (ListView) findViewById(R.id.drawer_list);
        if (mDrawerList == null) {
            throw new RuntimeException(
                    "Your content must have a ListView"
            );
        }


        mDrawerListener = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.string.drawer_open,
                R.string.drawer_close) {
            public void onDrawerClosed(View view) {
                onDrawerClose(view);
            }

            public void onDrawerOpened(View drawerView) {
                onDrawerOpen(drawerView);
            }

        };
        mDrawerLayout.setDrawerListener(mDrawerListener);
        mDrawerList.setOnItemClickListener(mOnClickListener);

        mDrawerList.setAdapter(mDrawerListAdapter);
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (mDrawerListener.onOptionsItemSelected(item)) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }


    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        mDrawerListener.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerListener.onConfigurationChanged(newConfig);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        ensureDrawerList();
        super.onRestoreInstanceState(savedInstanceState);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mDrawerLayout.closeDrawer(mDrawerList);
    }

    @Override
    public void setContentView(int layoutResID) {
        setContentView(getLayoutInflater().inflate(layoutResID, null));
    }

    @SuppressLint("InflateParams")
    @Override
    public void setContentView(View view) {
        mDrawerLayout = (DrawerLayout) getLayoutInflater().inflate(
                R.layout.drawer_activity, null);
        FrameLayout layout = (FrameLayout) mDrawerLayout
                .findViewById(R.id.content_frame);
        layout.addView(view);
        super.setContentView(mDrawerLayout);
    }

    public void onDrawerToggle() {
        if (mDrawerLayout.isDrawerOpen(mDrawerList)) {
            mDrawerLayout.closeDrawer(mDrawerList);
        } else {
            mDrawerLayout.openDrawer(mDrawerList);
        }
    }

    public void setDrawerListAdapter(ListAdapter adapter) {
        synchronized (this) {
            ensureDrawerList();
            mDrawerListAdapter = adapter;
        }
    }

    public void setDrawerListSelection(int position) {
        mDrawerList.setSelection(position);
        mDrawerList.setItemChecked(position, true);
    }

    public int getSelectedDrawerItemPosition() {
        return mDrawerList.getSelectedItemPosition();
    }

    public long getSelectedDrawerItemId() {
        return mDrawerList.getSelectedItemId();
    }

    protected void onListItemClick(ListView l, View v, int position, long id) {
        mDrawerList.setItemChecked(position, true);
        mDrawerLayout.closeDrawer(mDrawerList);
    }

    protected void onDrawerClose(View view) {
        supportInvalidateOptionsMenu();
    }

    protected void onDrawerOpen(View drawerView) {
        supportInvalidateOptionsMenu();
    }

    private AdapterView.OnItemClickListener mOnClickListener = new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v, int position,
                                long id) {
            onListItemClick((ListView) parent, v, position, id);
        }
    };

    public boolean isDrawerOpen() {
        return mDrawerLayout.isDrawerOpen(mDrawerList);
    }

    private void ensureDrawerList() {
        if (mDrawerList != null) {
            return;
        }
        mDrawerList = (ListView) findViewById(R.id.drawer_list);
    }

    public ListView getDrawerList() {
        return mDrawerList;
    }
}

drawer_activity.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 -->

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </FrameLayout>
    <!-- The navigation drawer -->

    <ListView
        android:id="@+id/drawer_list"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice" />

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

答案 1 :(得分:0)

我遇到了同样的问题,今晚我就修好了。

我有一个查看寻呼机/滑动标签设置,我想添加一个导航抽屉。

我根据this教程构建了我的导航抽屉以扩展到我的视图寻呼机。 当我试图将它扩展到我的viewpager类时,我不得不删除“navigator”的“fragmentactivity”扩展。这给了我现在的相同问题。我花了3个小时的研究才意识到,如果我在B类中扩展A类,那么只要A类“扩展”B类所需的“支持类”,那么你就不会有那个空指针问题。 / p>

这里是代码:navigation_draw.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
    android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<ListView
    android:id="@+id/left_drawer"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:background="#111"
    android:choiceMode="singleChoice"
    android:divider="@android:color/transparent"
    android:dividerHeight="0dp" />

android java:

package com.navigation.drawer.activity;
/**
* @author dipenp
*
* This activity will add Navigation Drawer for our application and all the code related to      navigation drawer.
* We are going to extend all our other activites from this BaseActivity so that every activity will        have Navigation Drawer in it.
* This activity layout contain one frame layout in which we will add our child activity layout.   
*/
public class BaseActivity extends Activity {

/**
 *  Frame layout: Which is going to be used as parent layout for child activity layout.
 *  This layout is protected so that child activity can access this 
 *  */
protected FrameLayout frameLayout;

/**
 * ListView to add navigation drawer item in it.
 * We have made it protected to access it in child class. We will just use it in child class to make item selected according to activity opened. 
 */

protected ListView mDrawerList;

/**
 * List item array for navigation drawer items.
 * */
protected String[] listArray = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };

/**
 * Static variable for selected item position. Which can be used in child activity to know which item is selected from the list. 
 * */
protected static int position;

/**
 *  This flag is used just to check that launcher activity is called first time
 *  so that we can open appropriate Activity on launch and make list item position selected accordingly.   
 * */
private static boolean isLaunch = true;

/**
 *  Base layout node of this Activity.   
 * */
private DrawerLayout mDrawerLayout;

/**
 * Drawer listner class for drawer open, close etc.
 */
private ActionBarDrawerToggle actionBarDrawerToggle;


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

    frameLayout = (FrameLayout)findViewById(R.id.content_frame);
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerList = (ListView) findViewById(R.id.left_drawer);

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

    // set up the drawer's list view with items and click listener
    mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, listArray));
    mDrawerList.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {

            openActivity(position);
        }
    });

    // enable ActionBar app icon to behave as action to toggle nav drawer
    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true);

    // ActionBarDrawerToggle ties together the the proper interactions between the sliding drawer and the action bar app icon
    actionBarDrawerToggle = new ActionBarDrawerToggle(
            this,                       /* host Activity */
            mDrawerLayout,              /* DrawerLayout object */
            R.drawable.ic_launcher,     /* nav drawer image to replace 'Up' caret */
            R.string.open_drawer,       /* "open drawer" description for accessibility */
            R.string.close_drawer)      /* "close drawer" description for accessibility */
    {
        @Override
        public void onDrawerClosed(View drawerView) {
            getActionBar().setTitle(listArray[position]);
            invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            super.onDrawerClosed(drawerView);
        }

        @Override
        public void onDrawerOpened(View drawerView) {
            getActionBar().setTitle(getString(R.string.app_name));
            invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            super.onDrawerOpened(drawerView);
        }

        @Override
        public void onDrawerSlide(View drawerView, float slideOffset) {
            super.onDrawerSlide(drawerView, slideOffset);
        }

        @Override
        public void onDrawerStateChanged(int newState) {
            super.onDrawerStateChanged(newState);
        }
    };
    mDrawerLayout.setDrawerListener(actionBarDrawerToggle);


    /**
     * As we are calling BaseActivity from manifest file and this base activity is intended just to add navigation drawer in our app.
     * We have to open some activity with layout on launch. So we are checking if this BaseActivity is called first time then we are opening our first activity.
     * */
    if(isLaunch){
         /**
          *Setting this flag false so that next time it will not open our first activity.
          *We have to use this flag because we are using this BaseActivity as parent activity to our other activity.
          *In this case this base activity will always be call when any child activity will launch.
          */
        isLaunch = false;
        openActivity(0);
    }
}

/**
 * @param position
 *
 * Launching activity when any list item is clicked.
 */
protected void openActivity(int position) {

    /**
     * We can set title & itemChecked here but as this BaseActivity is parent for other activity,
     * So whenever any activity is going to launch this BaseActivity is also going to be called and
     * it will reset this value because of initialization in onCreate method.
     * So that we are setting this in child activity.   
     */

    mDrawerLayout.closeDrawer(mDrawerList);
    BaseActivity.position = position; //Setting currently selected position in this field so that it will be available in our child activities.

    switch (position) {
    case 0:
        startActivity(new Intent(this, Item1Activity.class));
        break;
    case 1:
        startActivity(new Intent(this, Item2Activity.class));
        break;
    case 2:
        startActivity(new Intent(this, Item3Activity.class));
        break;
    case 3:
        startActivity(new Intent(this, Item4Activity.class));
        break;
    case 4:
        startActivity(new Intent(this, Item5Activity.class));
        break;

    default:
        break;
    }

    Toast.makeText(this, "Selected Item Position::"+position, Toast.LENGTH_LONG).show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.main, menu);
    return super.onCreateOptionsMenu(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 (actionBarDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }

    switch (item.getItemId()) {
    case R.id.action_settings:
        return true;

    default:
        return super.onOptionsItemSelected(item);
    }
}

/* 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_settings).setVisible(!drawerOpen);
    return super.onPrepareOptionsMenu(menu);
}

/* We can override onBackPressed method to toggle navigation drawer*/
@Override
public void onBackPressed() {
    if(mDrawerLayout.isDrawerOpen(mDrawerList)){
        mDrawerLayout.closeDrawer(mDrawerList);
    }else {
        mDrawerLayout.openDrawer(mDrawerList);
    }
}
}

我的寻呼机适配器代码(请注意,此寻呼机类仅扩展导航器,导航器扩展活动...如果您将导航器中的“扩展活动”更改为“扩展FragmentActivity”寻呼机,这将无效(您的问题)和抽屉将工作。因为这个视图寻呼机使用FragmentActivity):

public class StartActive extends Navigator implements TabListener
{
MyAdapter adapt;
ActionBar actionBar;
ViewPager viewPager = null;
String userName;


@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    //setContentView(R.layout.activity_start_active);
    getLayoutInflater().inflate(R.layout.activity_start_active, frameLayout);

    naviList.setItemChecked(position, true);
    setTitle(category[position]);
    if(getIntent().getExtras() != null)
    {
        userName = getIntent().getExtras().getString(MainActivity.KEY_USERNAME);
    }


    swipeTabs();    

}



public void swipeTabs()
{

    FragmentManager fragMan = getSupportFragmentManager();
    actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    adapt = new MyAdapter(fragMan);
    viewPager = (ViewPager) findViewById(R.id.startActive_Activity);
    viewPager.setAdapter(adapt);
    viewPager.setOnPageChangeListener(new OnPageChangeListener() 
    {

        @Override
        public void onPageSelected(int arg0) 
        {

            actionBar.setSelectedNavigationItem(arg0);
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) 
        {


        }

        @Override
        public void onPageScrollStateChanged(int arg0) 
        {


        }
    });
    android.app.ActionBar.Tab tab1 = actionBar.newTab();
    tab1.setText("User");
    tab1.setTabListener(this);

    android.app.ActionBar.Tab tab2 = actionBar.newTab();
    tab2.setText("Maps");
    tab2.setTabListener(this);

    android.app.ActionBar.Tab tab3 = actionBar.newTab();
    tab3.setText("Feed");
    tab3.setTabListener(this);

    actionBar.addTab(tab1);
    actionBar.addTab(tab2);
    actionBar.addTab(tab3);

}


@Override
public boolean onCreateOptionsMenu(Menu menu) 
{

    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.start_active, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) 
{
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment 
{

    public PlaceholderFragment() 
    {

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    {
        View rootView = inflater.inflate(R.layout.fragment_start_active, container, false);
        Log.d("Life cycles", "onCreateView");
        return rootView;
    }

}

@Override
public void onTabReselected(Tab arg0, FragmentTransaction arg1) 
{
    viewPager.setCurrentItem(arg0.getPosition());
}
@Override
public void onTabSelected(Tab arg0, FragmentTransaction arg1) 
{
    viewPager.setCurrentItem(arg0.getPosition());
}
@Override
public void onTabUnselected(Tab arg0, FragmentTransaction arg1) 
{

}

class MyAdapter extends FragmentPagerAdapter
{

    public MyAdapter(FragmentManager fm) 
    {
        super(fm);
    }

    @Override
    public Fragment getItem(int arg0) 
    {
        Bundle b = new Bundle();
        b.putString(MainActivity.KEY_USERNAME, userName);
        Fragment frag;
        switch(arg0)
        {
        case 1:
            return new GMaps();
        case 0:

            frag = new UserView();
            frag.setArguments(b);
            return frag;
        case 2:
            frag = new FeedView();
            frag.setArguments(b);
            return frag;
        }
        return null;

    }

    @Override
    public int getCount() 
    {
        return 3;
    }

}
} 

答案 2 :(得分:0)

如果您正在寻找ViewPager顶部的导航抽屉,您可以做什么:

如果您未正确了解Navigationdrawer,请查看此链接Click Here) 在相对布局

中使用此代码
<android.support.v4.widget.DrawerLayout
    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:id="@+id/custom_drawer_layout">


        <RelativeLayout
            android:id="@+id/relative"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">
            <android.support.v4.view.ViewPager
                android:id="@+id/pager"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                >
                <android.support.v4.view.PagerTabStrip
                    android:id="@+id/pager_tab_strip"
                    android:layout_width="match_parent"
                    android:layout_height="48sp"
                    android:layout_gravity="top"
                    android:background="@color/primary"
                    android:paddingBottom="20dp"
                    android:textAppearance="@style/PagerTabStripText" />

            </android.support.v4.view.ViewPager>


    </RelativeLayout>

    <fragment
        android:id="@+id/notification_drawer_fragement"
        android:layout_width="260dp"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:name="address to fragment class"
        tools:layout="@layout/notification_fragment"
        />
</android.support.v4.widget.DrawerLayout>

您将获得以下内容:

1是片段,2是viewPager enter image description here