禁用AppBarLayout的扩展

Nik*_*las 6 android android-support-library

我有一个工具栏和一个TabLayout以及一个包含在CollapsingToolbarLayout中的图像.这个gif几乎总结了一下:

https://raw.githubusercontent.com/vitovalov/TabbedCoordinatorLayout/master/art/demo.gif

这是XML:

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

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

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapse_toolbar"
            android:layout_width="match_parent"
            android:layout_height="250dp"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:id="@+id/header"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/photo"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"/>

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:gravity="top"
                android:minHeight="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:titleMarginTop="15dp"/>

            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:layout_gravity="bottom"
                app:tabIndicatorColor="@color/colorAccent"/>

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

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

    <android.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"/>

</android.support.design.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)

我想要实现的是,例如在Tab 2上,我不想让用户能够看到图像.因此,即使他试图将AppBarLayout拉下来,他也不应该在任何情况下看到图像.

调用appBarLayout.setExpanded(false);显示选项卡2会隐藏图像并将所有内容折叠回来.虽然当你按下AppBarLayout并向下滑动时,你可以恢复图像.情况并非如此.

我该如何防止这种行为?

我正在使用支持库的v23.1.1.对于图书馆的第22版,已经存在这个问题.但是,解决方法不再适用于版本23.

Ann*_*ire 16

我找到了一招!

  • 当我希望我的appbar保持折叠时:

    public void lockAppBarClosed() {
        mAppBarLayout.setExpanded(false, false);
        mAppBarLayout.setActivated(false);
        CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)mAppBarLayout.getLayoutParams();
        lp.height = (int) getResources().getDimension(R.dimen.toolbar_height);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 当我希望我的appbar再次展开和滚动时

    public void unlockAppBarOpen() {
        mAppBarLayout.setExpanded(true, false);
        mAppBarLayout.setActivated(true);
        CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)mAppBarLayout.getLayoutParams();
        lp.height = (int) getResources().getDimension(R.dimen.toolbar_expand_height);
    }
    
    Run Code Online (Sandbox Code Playgroud)

希望它能帮到你!


Bil*_*hon 12

Anne-Claire提供的技巧有效,但你最终失去了动画.我所做的是创建一个扩展AppBarLayout.Behavior类的自定义行为,允许我在每次选择时启用/禁用滚动.

public class CustomAppBarLayoutBehavior extends AppBarLayout.Behavior {

    private boolean shouldScroll = false;

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

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes, int type) {
        return shouldScroll;
    }

    @Override
    public boolean onTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent ev) {
        if(shouldScroll){
            return super.onTouchEvent(parent, child, ev);
        }else{
            return false;
        }
    }

    public void setScrollBehavior(boolean shouldScroll){
        this.shouldScroll = shouldScroll;
    }

    public boolean isShouldScroll(){
        return shouldScroll;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您应该将此行为应用于xml布局中的AppBarLayout

<android.support.design.widget.AppBarLayout
    android:id="@+id/app_bar_layout"
    android:layout_width="wrap_content"
    android:layout_height="@dimen/activity_main_toolbar_height_extended"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    android:fitsSystemWindows="true"
    android:elevation="4dp"
    app:layout_behavior="io.eighttails.mvp.widgets.CustomAppBarLayoutBehavior">
Run Code Online (Sandbox Code Playgroud)

然后你可以通过以下方式随意打开和关闭它:

CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
((CustomAppBarLayoutBehavior)layoutParams.getBehavior()).setScrollBehavior(true);
Run Code Online (Sandbox Code Playgroud)

要么

CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) mAppBarLayout.getLayoutParams();
((CustomAppBarLayoutBehavior)layoutParams.getBehavior()).setScrollBehavior(false);
Run Code Online (Sandbox Code Playgroud)


and*_*per 7

根据“ Bilthon”(此处)的答案,我认为在Kotlin中,此解决方案要短得多:

//allows to block scrolling of AppBarLayout /sf/answers/3366074841/
class BlockableAppBarLayoutBehavior(context: Context, attrs: AttributeSet) : AppBarLayout.Behavior(context, attrs) {
    var isShouldScroll = false

    override fun onStartNestedScroll(parent: CoordinatorLayout, child: AppBarLayout, directTargetChild: View, target: View, nestedScrollAxes: Int, type: Int) = isShouldScroll

    override fun onTouchEvent(parent: CoordinatorLayout, child: AppBarLayout, ev: MotionEvent) = isShouldScroll && super.onTouchEvent(parent, child, ev)

}
Run Code Online (Sandbox Code Playgroud)

用法:

滚动时禁用更改其大小:

((app_bar.layoutParams as CoordinatorLayout.LayoutParams).behavior as BlockableAppBarLayoutBehavior).isShouldScroll = false
Run Code Online (Sandbox Code Playgroud)

并启用:

((app_bar.layoutParams as CoordinatorLayout.LayoutParams).behavior as BlockableAppBarLayoutBehavior).isShouldScroll = false
Run Code Online (Sandbox Code Playgroud)

如果您有RecyclerView,并且希望也阻止它滚动,则也可以使用我发现的解决方案。

  • 这对我来说很有效,非常短而且干净。请记住在 AppBarLayout 内的 xml 中定义行为: ` app:layout_behavior="yourpath.BlockableAppBarLayoutBehavior" ` 否则在调用 layoutParams.behaviour 时您将得到一个 NPE (3认同)

归档时间:

查看次数:

8210 次

最近记录:

6 年,1 月 前