Android AppBarLayout+TabLayout+ViewPager实现导航栏渐变、tab标签悬浮固定效果

以前很羡慕别人的App,高端大气上档次,现在很多的界面都有这样的效果:要求导航栏渐变、页面Tab标签跟随页面滚动,悬浮固定到顶部。嗯嗯....大致表达出来就这个画面吧```还是直接上图吧。没有gif,只能截图了;

                     

网上已经有很多AppBarLayout的帖子了,这里我就不讲理论的东西了,直接上代码了。代码中有注释,根据注释,你可以实现自己的界面了。

提起那说一下,要使用AppBarLayout,先添加依赖

implementation 'com.android.support:design:27.1.1'

布局界面:

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:background="@color/white"
    android:orientation="vertical"
    tools:context=".activity.TextMyActivity">

    <!--AppBarLayout必须为CoordinatorLayout的直接子View-->

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:elevation="0dp">


        <!--CollapsingToolbarLayout Tab标签以上所有的布局都在这里边了,-->
        <!--小伙伴可以根据自己的需求来改变布局-->
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <!--app:layout_scrollFlags="scroll|exitUntilCollapsed" :就是控制导航栏样式的标签-->
            <!--这里我就不一一解释了,自己可以百度-->


            <ImageView
                android:layout_width="match_parent"
                android:layout_height="300dp"
                android:fitsSystemWindows="true"
                android:scaleType="fitXY"
                android:src="@mipmap/ranking_logo"
                app:layout_collapseMode="parallax" />

            <!--Toolbar以上的部分,就是你想要实现折叠效果的布局了,这里我就写了一个图片,-->
            <!--也可以放自己的东西,像:banner轮播图,你就可以放在这里,直接将Imageview换位Banner就好了-->

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@mipmap/test"
                android:paddingTop="20dp"
                app:contentInsetStart="0dp"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:title="@null">

                <!--Toolbar中就是导航栏的布局了-->


                <RelativeLayout
                    android:id="@+id/ib_back_layout"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

                    <ImageView
                        android:id="@+id/ib_back"
                        android:layout_width="20dp"
                        android:layout_height="20dp"
                        android:layout_centerVertical="true"
                        android:layout_marginLeft="10dp"
                        android:scaleType="fitCenter"
                        android:src="@mipmap/back" />


                    <TextView
                        android:id="@+id/toolbar_titletv"
                        style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerHorizontal="true"
                        android:layout_centerVertical="true"
                        android:drawablePadding="5dp"
                        android:ellipsize="end"
                        android:gravity="center"
                        android:lines="1"
                        android:scrollHorizontally="true"
                        android:text="首页"
                        android:textColor="@android:color/white" />


                    <ImageView
                        android:id="@+id/ib_right"
                        android:layout_width="20dp"
                        android:layout_height="20dp"
                        android:layout_alignParentRight="true"
                        android:layout_centerInParent="true"
                        android:layout_centerVertical="true"
                        android:layout_marginRight="10dp"
                        android:scaleType="fitCenter"
                        android:src="@mipmap/back" />
                </RelativeLayout>

            </android.support.v7.widget.Toolbar>


        </android.support.design.widget.CollapsingToolbarLayout>

        <!--Tab标签,要注意看布局的位置,在CollapsingToolbarLayout外边-->
        <android.support.design.widget.TabLayout
            android:id="@+id/infoPhoneTabLayou"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabIndicatorColor="@color/darkorange"
            app:tabSelectedTextColor="#e91b04"
            app:tabTextColor="#989898"></android.support.design.widget.TabLayout>


    </android.support.design.widget.AppBarLayout>

    <!--下边就是滑动的不聚了,要与上边的布局相关联,必须要有 app:layout_behavior="@string/appbar_scrolling_view_behavior"-->
    <!--这样才能实现折叠的效果-->
    <!--下方的滑动,可以用RecycleView,但是ListView是不好使的,你可以嵌套在NestedScrollView总试试-->
    <!--因为ViewPager就需要嵌套在其中才能实现。-->
    <!--这里还有一个坑,在外层必须要添加android:fillViewport="true"这个标签,让Viewpager填充,不然Viewpager会没有内容-->
    
    <android.support.v4.widget.NestedScrollView
        android:id="@+id/NestedScrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        android:overScrollMode="always"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">


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


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

</android.support.design.widget.CoordinatorLayout>

里边都有注释了,自己看看吧。

activity:

package com.project.teacherevaluation.activity;

import android.graphics.Color;
import android.support.annotation.Nullable;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.ViewGroup;

import com.project.teacherevaluation.R;
import com.project.teacherevaluation.adapters.RankingAdapter;
import com.project.teacherevaluation.base.BaseActivity;
import com.project.teacherevaluation.bean.RankingListBean;
import com.project.teacherevaluation.fragment.MineGradeFragment;
import com.project.teacherevaluation.fragment.MineTaskFragment;

import java.util.ArrayList;
import java.util.List;

public class TextMyActivity extends BaseActivity {
    //    private RecyclerView recyclerView;
    //
    //    private List<String> rankingList;
    //    private TextMyAdapter textMyAdapter;
    //    private LinearLayoutManager linearLayoutManager;

    private AppBarLayout appBarLayout;
    private Toolbar mToolbar;
    private TabLayout mTabLayout;
    private ViewPager mViewPager;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_text_my;
    }

    @Override
    public void initView(Bundle savedInstanceState) {
        //        recyclerView = findViewById(R.id.recyclerview);
        //        rankingList = new ArrayList<>();
        //        for (int i = 0; i < 20; i++) {
        //            rankingList.add("王喜福"+i);
        //        }
        //        textMyAdapter = new TextMyAdapter(rankingList, mContext);

        appBarLayout = findViewById(R.id.appBarLayout);
        mToolbar = findViewById(R.id.toolbar);
        mTabLayout = findViewById(R.id.infoPhoneTabLayou);
        mViewPager = findViewById(R.id.infoPhone_Fragment_pager);

        TabLayout();


        // 滑动监听“
        appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
//                 导航栏为固定颜色时:
                                mToolbar.setBackgroundColor(changeAlpha(getResources().getColor
                 (R.color.deepskyblue),Math.abs(verticalOffset * 1.0f) / appBarLayout.getTotalScrollRange()));
//                 导航栏有特有的背景时:直接改变透明度就行
//                mToolbar.setAlpha(Math.abs(verticalOffset * 1.0f) / appBarLayout
//                        .getTotalScrollRange());
                //mToolbar.setBackgroundResource(R.mipmap.ranking_logo);
            }
        });
    }

    @Override
    protected void loadNetData() {
        //        linearLayoutManager = new LinearLayoutManager(mActivity);
        //        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        //        recyclerView.setLayoutManager(linearLayoutManager);
        //        recyclerView.setAdapter(textMyAdapter);
    }


    /**
     * 根据百分比改变颜色透明度
     */
    public int changeAlpha(int color, float fraction) {
        int red = Color.red(color);
        int green = Color.green(color);
        int blue = Color.blue(color);
        int alpha = (int) (Color.alpha(color) * fraction);
        return Color.argb(alpha, red, green, blue);
    }


    /**
     * TabLayout
     * 初始化
     */
    private void TabLayout() {
        final List<String> list_Title = new ArrayList<>();
        list_Title.add("图文详情");
        list_Title.add("规格参数");

        final List<Fragment> fragmentList = new ArrayList<>();
        fragmentList.add(new MineGradeFragment());
        fragmentList.add(new MineTaskFragment());

        //FragmentPagerAdapter适用于Fragment比较少的情况,它会把每一个Fragment
        // 保存在内存中,不用每次切换的时候,去保存现场,切换回来在重新创建,所以用户体验比较好。而对于Fragment比较多的情况,需要切换的时候销毁以前的Fragment
        // 以释放内存,就可以使用FragmentStatePagerAdapter。

        //预加载
        mViewPager.setOffscreenPageLimit(fragmentList.size());
        mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
            @Override
            public Fragment getItem(int position) {
                return fragmentList.get(position);
            }

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

            @Override
            public void destroyItem(ViewGroup container, int position, Object object) {
                super.destroyItem(container, position, object);
            }

            @Nullable
            @Override
            public CharSequence getPageTitle(int position) {
                return list_Title.get(position);
            }
        });

        mTabLayout.setupWithViewPager(mViewPager);
    }

}

其中主要的就是滑动监听了,在其中做相应的操作就好了;好了,基本上就这样了。

这个是Tablayout+ViewPager的固定效果。其实我的初衷是想实现淘宝商品购物界面的TabLayout+AppBar的滑动锚点效果,但是单独的使用锚点效果还是能实现的,但是与AppBarLayout结合到一起后,就会出现滑动冲突、联动失效等bug。还请各位大神有没有好的帖子,留言推荐下!谢谢了~~

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值