DrawerLayout + NavigationView 侧滑菜单,ViewPager + Fragment 快速构建主界面

安卓的 Material Design 添加了不少的新控件,可以帮助我们快速开发。比如侧滑菜单、浮动按钮、导航条(不是以前蛋疼的ActionBar)、菜单条,还自带了不少特效,当然只要从API 17以上才有效果。有的是19,有的是21。所以,如果要做兼容的话,也是比较蛋疼的。但好在目前的趋势是,4.4一下的手机也是越来越少了,最好都是5.0的就好了。

以前的各种开源大神写的依赖库,虽然很好用,但是没用一个依赖库,都要琢磨一番,并且每个公司的设计都不一样,还要修改一番,心碎啊。有了新的,我们淡然得研究一番了。

侧滑菜单 + ViewPager + Fragment + 导航条,快速搭建一个项目的主界面,还是比较爽的,代码也是比较清晰的,先上图吧。

DrawerLayout + NavigationView 侧滑菜单,ViewPager + Fragment 快速构建主界面_第1张图片

DrawerLayout + NavigationView 侧滑菜单,ViewPager + Fragment 快速构建主界面_第2张图片

DrawerLayout + NavigationView 侧滑菜单,ViewPager + Fragment 快速构建主界面_第3张图片

先看布局代码

"1.0" encoding="utf-8"?>
.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
                                        xmlns:app="http://schemas.android.com/apk/res-auto"
                                        android:id="@+id/drawerLayout"
                                        android:layout_width="match_parent"
                                        android:layout_height="match_parent"
                                        android:clipToPadding="true"
                                        android:fitsSystemWindows="true">

    .support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
                                                     android:layout_width="match_parent"
                                                     android:layout_height="match_parent"
                                                     android:orientation="vertical">

        .support.design.widget.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            .support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/material_primary_dark"
                app:layout_scrollFlags="scroll|enterAlways"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

            .support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/material_primary_dark"
                app:tabMode="scrollable"
                app:tabSelectedTextColor="@android:color/white"
                app:tabTextColor="#aaffffff"/>
        .support.design.widget.AppBarLayout>

        .support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

    .support.design.widget.CoordinatorLayout>

    .support.design.widget.NavigationView
        android:id="@+id/navigationView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/head_navigation_view"
        app:menu="@menu/menu_navigation_view"/>

.support.v4.widget.DrawerLayout>

侧滑菜单 NavigationView 一定要包在 DrawerLayout 的布局中。CoordinatorLayout 就相当于一个LinearLayout,AppBarLayout 就用来包裹导航条的。至于其中的一些属性,可以看我上篇文章的。

其中 NavigationView 的 app:headerLayout=”@layout/head_navigation_view” 就是你在图片上看到的一个美女玩手机背景图片 + ImageView + TextView 。

其中 NavigationView 的 app:menu=”@menu/menu_navigation_view” 就导航下面的每一条 Item 。

主界面代码

package com.example.zhou.materialtest;

import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.design.widget.TabLayout;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

import com.zhou.ui.adapter.HomeFragmentAdapter;

import java.util.Arrays;

public class MainActivity extends AppCompatActivity {

    private Toolbar mToolbar;
    private TabLayout mTabLayout;
    private ViewPager mViewPager;
    private NavigationView mNavigationView;
    private DrawerLayout mDrawerLayout;

    private HomeFragmentAdapter mHomeFragmentAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        initView();
        initToolbar();
        initViewPager();
        initNavigationView();
    }

    private void initView() {
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        mTabLayout = (TabLayout) findViewById(R.id.tabs);
        mViewPager = (ViewPager) findViewById(R.id.viewpager);
        mNavigationView = (NavigationView) findViewById(R.id.navigationView);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
    }

    private void initViewPager() {
        String[] titles = {"科技新闻", "靓丽美女", "极客信息", "德莱联盟"};
        mHomeFragmentAdapter = new HomeFragmentAdapter(getSupportFragmentManager(), Arrays.asList(titles));
        mViewPager.setAdapter(mHomeFragmentAdapter);
        mTabLayout.setupWithViewPager(mViewPager); // 将TabLayout和ViewPager关联起来。
        mTabLayout.setTabsFromPagerAdapter(mHomeFragmentAdapter); // 给Tabs设置适配器

        mViewPager.setCurrentItem(0);
    }

    private void initToolbar() {
        setSupportActionBar(mToolbar);
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        mToolbar.setTitle("greek lee");
        mToolbar.setSubtitle("zhou");
        mToolbar.setLogo(R.mipmap.ic_launcher);
        mToolbar.setNavigationIcon(R.mipmap.ic_launcher);
        // getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        // mToolbar.setOnMenuItemClickListener(this);
    }

    private void initNavigationView() {

        mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {

            private MenuItem mPreMenuItem;

            @Override
            public boolean onNavigationItemSelected(MenuItem item) {
                if (mPreMenuItem != null) {
                    mPreMenuItem.setChecked(false);
                }

                Toast.makeText(getApplicationContext(), item.getTitle(), Toast.LENGTH_SHORT).show();

                item.setChecked(true);
                mDrawerLayout.closeDrawers();
                mPreMenuItem = item;
                return true;
            }
        });

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            // 打开抽屉侧滑菜单
            mDrawerLayout.openDrawer(GravityCompat.START);
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.menu_home, menu);
        return super.onCreateOptionsMenu(menu);
    }

    private long exitTime = 0;

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
            // 按下的如果是BACK,同时没有重复.
            if ((System.currentTimeMillis() - exitTime) > 2000) {
                Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();
                exitTime = System.currentTimeMillis();
            } else {
                finish();
            }
        }
        return true;
    }


}

没写什么注释,不是好习惯。不过代码都很简单,相信都能搞定的。

主要是初始化一下ViewPager,在HomeFragmentAdapter 里面塞了4个Fragment,通过 setupWithViewPager() 方法让 ViewPager 和TabLayout 联动起来。

然后就是初始化导航条 Toolbar,设置了一些参数,返回图片,文字,还有很多,大家可以自己找下。

然后初始化侧滑菜单,主要是监听 setNavigationItemSelectedListener(),菜单的点击事件。

再就是写了一个菜单,就一个搜索按钮和一个朋友按钮,这样该有的都有了。需要什么,完全可以自定义。

代码也不是很多,ViewPager适配器 HomeFragmentAdapter,主要注意 getPageTitle() 这个方法,一定要重写,这个适合 TabLayout 联动的关键(视觉上)。

package com.zhou.ui.adapter;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;

import com.zhou.ui.fragment.Fragment1;
import com.zhou.ui.fragment.Fragment2;
import com.zhou.ui.fragment.Fragment3;
import com.zhou.ui.fragment.Fragment4;

import java.util.List;

/**
 * Created by zhou on 2016/6/1.
 */
public class HomeFragmentAdapter extends FragmentStatePagerAdapter {

    private List mTitles;

    public HomeFragmentAdapter(FragmentManager fm, List mTitles) {
        super(fm);
        this.mTitles = mTitles;
    }

    @Override
    public Fragment getItem(int position) {
        String str = mTitles.get(position);
        Fragment fragment = null;
        switch (position) {
            case 0:
                fragment = Fragment1.newInstance(str);
                break;
            case 1:
                fragment = Fragment2.newInstance(str);
                break;
            case 2:
                fragment = Fragment3.newInstance(str);
                break;
            case 3:
                fragment = Fragment4.newInstance(str);
                break;
        }
        return fragment;
    }

    @Override
    public int getCount() {
        return mTitles.size();
    }

    /**
     * 联动 TabLayout 上的 Title
     * @param position
     * @return
     */
    @Override
    public CharSequence getPageTitle(int position) {
        return mTitles.get(position);
    }

}

注意几点

1.API 要17以上,如果要沉浸栏,就需要19以上,我用的是19。比较懒,没写兼容啦~

2.继承 AppCompatActivity 类。

3.AndroidManifest.xml 中的主题要加上,继承自 Theme.AppCompat 一类的,这是必须

<item name="windowActionBar">falseitem>
<item name="windowNoTitle">trueitem>

4.如果要用沉浸栏,要加上:颜色自定

<item name="android:windowTranslucentStatus">trueitem>
<item name="android:windowDrawsSystemBarBackgrounds">trueitem>
<item name="android:statusBarColor">@android:color/transparentitem>
-- 附上我的引用的主题 -->

最近在转 Android Studio,构建出的项目文件很大,没办法上传 CSDN了,所有上传了 GitHub,如果是Eclipse,自己 copy 一下吧,只是导包比较烦。不知道是我电脑卡,还是 AS 卡。夜深了,撸一把,明天上班了。

源码地址:http://download.csdn.net/detail/u012301841/9716021

你可能感兴趣的:(Android,开发记录)