Android Toolbar+DrawerLayout+PagerSlidingTabStrip实现仿csdn侧滑菜单

Toolbar是Android5.0新出的一个工具栏,相对于ActionBar ToolBar的位置可以随意摆放,DrawerLayout则是SlidingDrawer的升级版,我们知道SlidingDeawer并不是是支持所有方向的拉动,它只支持从右到左,从下到上,所以有一定的局限性,而DrawerLayout则可以随意设置,PagerSlidingTabStrip是github上的一个开源库,它是配合viewPager使用的一个导航栏。下面来一步步实现我们的目标。

首先先从github上吧这个项目拷下来,其实这就一个类继承了水平的ScrollView,然后自定义了一些属性,所以我就直接把这个类复制到项目中,源码最后会给出,或者可以直接在github上下载,下载的链接为:https://github.com/astuetz/PagerSlidingTabStrip,可以下载然后把这个类拷贝到项目中作为一个工具类使用,它需要一些自定义的属性,所以直接将属性拷贝到values/attrs.xml文件夹下面,属性为:

<declare-styleable name="PagerSlidingTabStrip">
        <attr name="pstsIndicatorColor" format="color" />
        <attr name="pstsUnderlineColor" format="color" />
        <attr name="pstsDividerColor" format="color" />
        <attr name="pstsIndicatorHeight" format="dimension" />
        <attr name="pstsUnderlineHeight" format="dimension" />
        <attr name="pstsDividerPadding" format="dimension" />
        <attr name="pstsTabPaddingLeftRight" format="dimension" />
        <attr name="pstsScrollOffset" format="dimension" />
        <attr name="pstsTabBackground" format="reference" />
        <attr name="pstsShouldExpand" format="boolean" />
        <attr name="pstsTextAllCaps" format="boolean" />
    </declare-styleable>

然后还有一个tab背景选择器,放在了drawable文件夹下面;

拷贝完成之后我们的准备工作就做好了,下面是代码一步步实现,首先是页面布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/dl"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <!-- 内容-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:background="#ffffff"
                android:minHeight="?attr/actionBarSize">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:text="头条"
                    android:textColor="#000"
                    android:textSize="16sp" />

                <ImageView
                    android:layout_width="16dp"
                    android:layout_height="16dp"
                    android:layout_gravity="center_vertical|right"
                    android:layout_marginRight="20dp"
                    android:src="@drawable/search" />

                <ImageView
                    android:layout_width="16dp"
                    android:layout_height="16dp"
                    android:layout_gravity="center_vertical|right"
                    android:layout_marginRight="20dp"
                    android:src="@drawable/add_attention" />
            </android.support.v7.widget.Toolbar>

            <com.sjr.toolbar.PagerSlidingTabStrip
                android:id="@+id/pss_tab"
                android:layout_width="match_parent"
                android:layout_height="48dp" />

            <android.support.v4.view.ViewPager
                android:id="@+id/vp_fragment"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </LinearLayout>

        <!-- 侧滑菜单 -->

        <LinearLayout
            android:id="@+id/ll_drawer"
            android:layout_width="200dp"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:background="@drawable/drawer"
            android:orientation="vertical"
            android:padding="8dp">
            <!--这里可以放侧滑菜单的界面布局-->
        </LinearLayout>
    </android.support.v4.widget.DrawerLayout>

</LinearLayout>
因为Toolbar是跟着内容一起被左边侧滑菜单覆盖的所以我把它包在了内容布局里面,这也是Toolbar的一个优势,我们可以直接把它当做一个ViewGroup来使用,它的位置可以随意摆放,内容部分的布局我用了一个线性布局,将Toobar、PagerSlidingTabStrip、ViewPager依次摆放,左边的侧滑菜单布局可以照着业务需求进行布局,这里为了省事我直接截了一张图..布局说明完毕,下面是MainActivity的逻辑实现:

public class MainActivity extends AppCompatActivity {

    private Toolbar mToolbar;
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private PagerSlidingTabStrip mPagerSlidingTabStrip;
    private ViewPager mViewPager;
    private final String[] mDatas = {"最新", "前端", "移动开发", "语言", "游戏&图像"
            , "系统&安全", "loT", "数据库", "业界"
            , "云计算", "大数据", "研发工具", "软件工程"};
    private List<Fragment> container;

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


    private void initView() {
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.dl);
        mPagerSlidingTabStrip = (PagerSlidingTabStrip) findViewById(R.id.pss_tab);
        mViewPager = (ViewPager) findViewById(R.id.vp_fragment);

        mToolbar.setTitle("");//把Toolbar的标题设置为空
        setSupportActionBar(mToolbar);//设置Toolbar
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar,
                R.string.drawer_open, R.string.drawer_close);//触发器
        mDrawerToggle.syncState();//同步状态
        mDrawerLayout.addDrawerListener(mDrawerToggle);//设置监听
    }

    private void initFragment() {
        container = new ArrayList<>();
        for (int i = 1; i <= mDatas.length; i++) {//这里应该是根据实际业务添加Fragment,我为了演示所以直接循环添加一个Fragment而已
            TestFragment fragment = new TestFragment();
            container.add(fragment);
        }
    }

    private void initDatas() {
        mViewPager.setAdapter(new MPagerAdapter(getSupportFragmentManager()));//viewpager设置适配器
        mPagerSlidingTabStrip.setViewPager(mViewPager);//把viewpager跟pagerSlidingTabStrip进行绑定

        mPagerSlidingTabStrip.setTextSize(40); //标签字体大小
        mPagerSlidingTabStrip.setIndicatorColor(Color.BLUE); //标签下的横线颜色
        mPagerSlidingTabStrip.setIndicatorHeight(4);//标签下的横线高度
        mPagerSlidingTabStrip.setIndicatorColor(Color.RED);//标签下横线的颜色
        mPagerSlidingTabStrip.setDividerColor(Color.TRANSPARENT);//每个标签间的分割线
        mPagerSlidingTabStrip.setBackgroundColor(Color.parseColor("#F6F6F6"));//标签背景
        mPagerSlidingTabStrip.setSelectedTextColor(Color.RED);//选中标签的文字颜色
        mPagerSlidingTabStrip.setTextColor(Color.BLACK);//标签颜色
    }


    public class MPagerAdapter extends FragmentStatePagerAdapter {


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

        @Override
        public CharSequence getPageTitle(int position) {
            return mDatas[position];
        }

        @Override
        public int getCount() {
            return container == null ? 0 : container.size();
        }

        @Override
        public Fragment getItem(int position) {
            return container == null ? null : container.get(position);
        }

    }
}
我觉得我注释已经写得很详细了..这里就不再多累赘,值得说一说的是FragmentStatePagerAdapter,之所以不用FragmentPagerAdapter是因为他们的缓存策略是不同的,FragmentPagerAdapter会对浏览过的Fragment进行缓存,对每个界面都缓存当界面一多时就会增加程序占用的内存,还有一个是当我们滑动几个Fragment之后再返回第一个时会出现空白。而FragmentStatePagerAdapter会保存当前界面,下一个界面和上一个界面(如果有),其他的会销毁,注意的是使用FragmentStatePagerAdapter可能会有内存回收不正常的情况,比如Fragment上有EditText保存了焦点而造成Fragment没有被正常回收,这种情况可能会造成内存溢出。所以当tabs少的时候就是用FragmentPagerAdapter,而tabs多的时候就是用FragmentStatePagerAdapter。

到这里就已经完成需求了,下面是demo的效果(请原谅我不会录制视频...):


demo源码:http://download.csdn.net/detail/lxzmmd/9522072



原创文章 17 获赞 14 访问量 3万+

猜你喜欢

转载自blog.csdn.net/lxzmmd/article/details/51422177
今日推荐