android 吸顶(悬浮)效果+下拉刷新 CoordinatorLayout+AppBarLayout+tablayout+viewpager

最近有个一页面需要实现吸顶效果,本打算用scrollview+tablayout+viewpager实现,要处理触摸事件解决冲突等一些问题,出来后效果不是很好,最后发现CoordinatorLayout+AppBarLayout+tablayout+viewpager挺好用,效果也挺好,下面说一下具体操作:

1、首先是主页面布局:

采用 SwipeRefreshLayout+CoordinatorLayout+AppBarLayout+CollapsingToolbarLayout+tablayout+viewpager:

   SwipeRefreshLayout 负责下拉刷新;

   CoordinatorLayout 协调者布局

   AppBarLayout 工具栏;

   CollapsingToolbarLayout上滑时回隐藏的布局;

   tablayout 这个是悬浮的布局(要增加其他悬浮控件,只需要在AppBarLayout里,CollapsingToolbarLayout布局外添加就可以

 viewpager:左右滑动的页面

     代码如下:

<android.support.v4.widget.SwipeRefreshLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/swipe_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:addStatesFromChildren="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:id="@+id/appbar_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            android:visibility="visible"
            app:layout_behavior="com.yongdou.wellbeing.newfunction.customview.CustomBehavior">

            <android.support.design.widget.CollapsingToolbarLayout
                android:id="@+id/collapsing_toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:contentScrim="@android:color/transparent"
                app:expandedTitleGravity="top"
                app:layout_scrollFlags="exitUntilCollapsed|scroll">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">

                    <com.youth.banner.Banner
                        android:id="@+id/banner"
                        android:layout_width="match_parent"
                        android:layout_height="180dp" />
                </LinearLayout>
            </android.support.design.widget.CollapsingToolbarLayout>
        <!--如果还想悬浮其他控件放在这里即可-->
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="-16dp"
                android:background="@drawable/bg_home_dyna"
                app:layout_behavior="@string/appbar_scrolling_view_behavior">
                <android.support.design.widget.TabLayout
                    android:layout_weight="1"
                    android:id="@+id/tab_dynatypes"
                    style="@style/custom_tab"
                    android:layout_width="fill_parent"
                    android:layout_height="@dimen/dp_60"
                    android:paddingTop="@dimen/dp_10"
                    app:layout_behavior="@string/appbar_scrolling_view_behavior"
                    app:tabIndicatorHeight="0dip"
                    app:tabMode="scrollable" />
                <ImageView
                    android:paddingTop="@dimen/dp_10"
                    android:id="@+id/iv_entry_opus"
                    android:layout_toRightOf="@+id/tab_dynatypes"
                    android:layout_width="@dimen/dp_40"
                    android:layout_gravity="center_vertical"
                    android:background="@mipmap/opus_label"
                    android:layout_height="@dimen/dp_40" />
            </LinearLayout>
        </android.support.design.widget.AppBarLayout>

        <android.support.v4.view.ViewPager
            android:id="@+id/vp_dynas_of_type"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    </android.support.design.widget.CoordinatorLayout>

</android.support.v4.widget.SwipeRefreshLayout>
2、控件初始化以及一些事件冲突的解决(这里主要是下拉刷新与整体下拉的冲突)

  初始化控件

@BindView(R.id.appbar_layout)
AppBarLayout appBarLayout;
@BindView(R.id.swipe_layout)
SwipeRefreshLayout swipeLayout;
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
    @Override
    public boolean canDrag(@NonNull AppBarLayout appBarLayout) {
        return true;
    }
});
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
    @Override
    public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {

        if (verticalOffset >= 0) {
            swipeLayout.setEnabled(true);
        } else {
            swipeLayout.setEnabled(false);
        }
    }
});

 

3、再添加上行为处理的类,代码如下:

/**
 * Created by Forever
 * on 2020/5/27 0027.
 */
public class CustomBehavior extends  AppBarLayout.Behavior {
    private OverScroller mScroller;
    public CustomBehavior() {
    }

    public CustomBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
        getParentScroller(context);
    }

    /**
     * 反射获得滑动属性。
     *
     * @param context
     */
    private void getParentScroller(Context context) {
        if (mScroller != null) {
            return;
        }
        mScroller = new OverScroller(context);
        try {
            Class<?> reflex_class = getClass().getSuperclass().getSuperclass();//父类AppBarLayout.Behavior  父类的父类   HeaderBehavior
            Field fieldScroller = reflex_class.getDeclaredField("mScroller");
            fieldScroller.setAccessible(true);
            fieldScroller.set(this, mScroller);
        } catch (Exception e) {}
    }
    //fling上滑appbar然后迅速fling下滑recycler时, HeaderBehavior的mScroller并未停止, 会导致上下来回晃动
    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed, int type) {
        if(mScroller!=null){ //当recyclerView 做好滑动准备的时候 直接干掉Appbar的滑动
            if (mScroller.computeScrollOffset()) {
                mScroller.abortAnimation();
            }
        }
        if (type == ViewCompat.TYPE_NON_TOUCH&&getTopAndBottomOffset() == 0) { //recyclerview 鸡儿的 惯性比较大 会顶在头部一会儿  到头直接干掉它的滑动
            ViewCompat.stopNestedScroll(target, type);
        }
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
    }

    @Override
    public boolean onTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent e) {
        switch (e.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                break;
        }

        return super.onTouchEvent(parent,child,e);
    }
}

4、然后再添加上你的tablayout初始化 viewpager的初始化以及适配器 (注意在fragment中布局根节点需要实现的

NestedScrollingChild2接口的布局(例如:recyclerview)

  ok,结束!

好的,以下是一个简单的布局代码示例,可以实现 NestedScrollView 嵌套 tablayout+viewpager,同时也有吸顶效果。 ```xml <androidx.coordinatorlayout.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.core.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <!-- 这里是 NestedScrollView 中的内容 --> </androidx.core.widget.NestedScrollView> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <com.google.android.material.tabs.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabMode="scrollable" app:tabGravity="fill"/> </com.google.android.material.appbar.AppBarLayout> <androidx.viewpager.widget.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"/> </androidx.coordinatorlayout.widget.CoordinatorLayout> ``` 其中,NestedScrollView 中的内容可以自行替换为任意布局。在 AppBarLayout 中,我们放置了一个 TabLayout,这里设置了 `tabMode="scrollable"` 和 `tabGravity="fill"`,可以让 TabLayout 支持滚动,并且填充整个父布局的宽度。ViewPager 也设置了 `app:layout_behavior="@string/appbar_scrolling_view_behavior"`,这样可以让 ViewPager 支持与 TabLayout 的联动滑动。 最后需要注意的是,在布局文件中需要引入以下依赖: ```xml <com.google.android.material:material:1.2.1> ``` 希望这个示例代码对你有所帮助!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值