美文网首页Android开发程序员Android开发经验谈
仿哔哩哔哩客户端首页+抽屉式导航的实现

仿哔哩哔哩客户端首页+抽屉式导航的实现

作者: Android架构 | 来源:发表于2019-06-04 20:25 被阅读2次

    本文使用Toobar+DrawerLayout+NavigationView仿哔哩哔哩客户端首页+抽屉式导航,同时实现了沉浸式状态栏的效果。

    一、效果图

    图片及图标色彩等没有刻意模仿,结构相同。

    上图可以看出实现了沉浸式状态栏。

    二、页面布局

    <android.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/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:fitsSystemWindows="true">
    
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <include layout="@layout/app_bar"></include>
        </FrameLayout>
    
        <android.support.design.widget.NavigationView
            android:id="@+id/navigation"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:background="@color/white"
            app:headerLayout="@layout/view_nav"
            app:menu="@menu/menu_nav"/>
    
    </android.support.v4.widget.DrawerLayout>
    
    

    在这里可以看到,最外层布局是DrawerLayout,里面嵌套了两个布局,一层是FrameLayout,其中通过include进来的主界面内容,第二层是侧滑的内容,即NavigationView。

    主界面布局
    <android.support.design.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".home.MainActivity">
    
        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="@style/Theme.AppCompat.Light"
            app:elevation="0dp">
    
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@color/colorPrimary"
                app:popupTheme="@style/AppTheme.PopupOverlay"/>
            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:tabBackground="@color/colorPrimary"
                app:tabIndicatorColor="@color/white">
            </android.support.design.widget.TabLayout>
    
        </android.support.design.widget.AppBarLayout>
        <android.support.v4.view.ViewPager
            android:id="@+id/vp_moudle"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">
        </android.support.v4.view.ViewPager>
    
    </android.support.design.widget.CoordinatorLayout>
    
    

    主界面布局先是CoordinatorLayout嵌套了AppBarLayout以及ViewPager。AppBarLayout中嵌套了ToolBar以及TabLayout。在Activity中让ViewPager和TabLayout关联,实现ViewPager页面滑动时对应标签的联动。

    抽屉界面布局

    抽屉界面由NavigationView来实现,主要由两部分来实现,包含导航栏头部,以及菜单栏。
    导航栏头部

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                    android:orientation="vertical"
                    android:layout_width="match_parent"
                    android:layout_height="150dp"
                    android:background="@drawable/nav_header">
        <ImageView
    
            android:layout_marginBottom="10dp"
            android:layout_marginLeft="20dp"
            android:src="@drawable/nav_header_image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/iv_user_photo"
            android:layout_above="@+id/tv_login"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:textSize="12sp"
            android:text="点击头像登录"
            android:textColor="@color/white"
            android:padding="8dp"
            android:layout_marginLeft="20dp"
            android:layout_marginBottom="20dp"
            android:gravity="center"
            android:id="@+id/tv_login"
            android:layout_alignParentBottom="true"/>
    
    </RelativeLayout>
    
    

    菜单栏

    <menu xmlns:android="http://schemas.android.com/apk/res/android"
      >
      <group android:checkableBehavior="single"
          >
          <item android:title="首页" android:id="@+id/mn_home" android:icon="@drawable/menu_home"></item>
          <item android:title="离线缓存" android:id="@+id/mn_download" android:icon="@drawable/menu_download"></item>
          <item android:title="我的收藏" android:id="@+id/mn_store" android:icon="@drawable/menu_store"></item>
          <item android:title="个性化信息" android:id="@+id/mn_personal" android:icon="@drawable/menu_personal" ></item>
          <item android:title="设置与帮助" android:id="@+id/mn_setting" android:icon="@drawable/menu_setting"></item>
          <item android:title="注销" android:id="@+id/mn_out" android:icon="@drawable/menu_out"></item>
      </group>
    </menu>
    
    

    这两部分都在NavigationView布局中引用了,直接生效。
    注意:菜单栏的彩色图标的颜色不会生效,默认展示为灰色。需要在Activity中设置如下代码才会恢复彩色:
    navigationView.setItemIconTintList(null);

    三、MainActivity中代码

    设置ToolBar

     /**
         * 设置ToolBar
         */
        private void setToolBar() {
            setSupportActionBar(mToolbar);
            ActionBar actionBar = getSupportActionBar();
            //菜单按钮可用
            actionBar.setHomeButtonEnabled(true);
            //回退按钮可用
            actionBar.setDisplayHomeAsUpEnabled(true);
            //将drawlayout与toolbar绑定在一起
            ActionBarDrawerToggle abdt = new ActionBarDrawerToggle(this, mAmDl, mToolbar, R.string.app_name, R.string.app_name);
            abdt.syncState();//初始化状态
            //设置drawlayout的监听事件 打开/关闭
            mAmDl.setDrawerListener(abdt);
            //actionbar中的内容进行初始化
            mToolbar.setTitle("Live圈");//设置标题
            mToolbar.setTitleTextColor(getResources().getColor(R.color.white));
        }
    
    

    若想在ToolBar中添加菜单栏,可以设置布局,然后在MainActivity中调用onCreateOptionsMenu进行初始化。详情可以下载源码(下面有链接)。
    沉浸式状态栏

    4.4及其以上都是可以实现沉浸式状态栏效果的,5.0及其以上可以直接在主题中设置颜色,或者调用 Window 类中的 setStatusBarColor(int color) 来实现,这两种方式在5.0上都比较简单,但是如何兼容到4.4,这是一个需要解决的问题。

    解决思路:

    给状态栏设置颜色

    先设置状态栏透明属性;
    给根布局加上一个和状态栏一样大小的矩形View(色块),添加到顶上;
    然后设置根布局的 FitsSystemWindows 属性为 true,此时根布局会延伸到状态栏,处在状态栏位置的就是之前添加的色块,这样就给状态栏设置上颜色了。

    /**
         * 为DrawerLayout 布局设置状态栏变色
         *
         * @param activity       需要设置的activity
         * @param drawerLayout   DrawerLayout
         * @param color          状态栏颜色值
         * @param statusBarAlpha 状态栏透明度
         */
        public static void setColorForDrawerLayout(Activity activity, DrawerLayout drawerLayout, @ColorInt int color,
                                                   int statusBarAlpha) {
            //系统小于4.4
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
                return;
            }
            //5.0以上 直接设置状态栏为透明色
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
            } else {
                //4.4-5.0之间先设置透明状态栏
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            }
            // 生成一个状态栏大小的矩形
            // 添加 statusBarView 到布局中
            ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
            View fakeStatusBarView = contentLayout.findViewById(FAKE_STATUS_BAR_VIEW_ID);
            if (fakeStatusBarView != null) {
                if (fakeStatusBarView.getVisibility() == View.GONE) {
                    fakeStatusBarView.setVisibility(View.VISIBLE);
                }
                fakeStatusBarView.setBackgroundColor(color);
            } else {
                contentLayout.addView(createStatusBarView(activity, color), 0);
            }
            // 内容布局不是 LinearLayout 时,设置padding top
            if (!(contentLayout instanceof LinearLayout) && contentLayout.getChildAt(1) != null) {
                contentLayout.getChildAt(1)
                        .setPadding(contentLayout.getPaddingLeft(), getStatusBarHeight(activity) + contentLayout.getPaddingTop(),
                                contentLayout.getPaddingRight(), contentLayout.getPaddingBottom());
            }
            // 设置属性
            setDrawerLayoutProperty(drawerLayout, contentLayout);
           //将状态栏设置一定的透明度
            addTranslucentView(activity, statusBarAlpha);
        }
    
    

    通过以上内容就达到了模仿哔哩哔哩客户端首页+抽屉式导航的效果,具体图标及颜色没有刻意地模仿。
    源码下载 里面包含一些乱七八糟地东西,没有好好整理。只需要了解MainActivity相关内容即可。

    自己是从事了七年开发的Android工程师,不少人私下问我,2019年Android进阶该怎么学,方法有没有?

    没错,年初我花了一个多月的时间整理出来的学习资料,希望能帮助那些想进阶提升Android开发,却又不知道怎么进阶学习的朋友。【包括高级UI、性能优化、架构师课程、NDK、Kotlin、混合式开发(ReactNative+Weex)、Flutter等架构技术资料】,希望能帮助到您面试前的复习且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。

    资料获取方式:加入Android架构交流QQ群聊:513088520 ,进群即领取资料!!!

    点击链接加入群聊【Android移动架构总群】:加入群聊

    资料大全

    相关文章

      网友评论

        本文标题:仿哔哩哔哩客户端首页+抽屉式导航的实现

        本文链接:https://www.haomeiwen.com/subject/wrphxctx.html