如何禁用 NestedScrollView&CollapsingToolbarLayout 的滚动,例如当下面没有更多内容时? [英] How to disable scrolling of NestedScrollView&CollapsingToolbarLayout, for example when there is no more content below?

本文介绍了如何禁用 NestedScrollView&CollapsingToolbarLayout 的滚动,例如当下面没有更多内容时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景

我尝试添加与许多应用程序相同的功能,其中屏幕的上部区域会根据滚动的内容缩小和扩展.

为此,我使用了 Google 的设计库,如

虽然这是我滚动到底部时想要的(取自通讯录应用):

我也在尝试修复

这就是不阻止滚动的错误的行为方式:

我的尝试

我尝试使用

所以要为您的#1 找到解决方案,您需要计算NestedScrollView 的高度,然后如果它小于屏幕高度,我们固定工具栏的高度.

简而言之,您可以将 activity_detail.xml 更新为以下内容:

<android.support.design.widget.AppBarLayoutandroid:id="@+id/appbar"android:layout_width="match_parent"android:layout_height="@dimen/detail_backdrop_height"机器人:fitsSystemWindows =真"android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"><android.support.design.widget.CollapsingToolbarLayoutandroid:id="@+id/collapsing_toolbar"android:layout_width="match_parent"android:layout_height="match_parent"机器人:fitsSystemWindows =真"app:contentScrim="?attr/colorPrimary"app:layout_scrollFlags="scroll|exitUntilCollapsed"><图像视图android:id="@+id/背景"android:layout_width="match_parent"android:layout_height="match_parent"机器人:fitsSystemWindows =假"android:scaleType="centerCrop"app:layout_collapseMode="视差"/><android.support.v7.widget.Toolbarandroid:id="@+id/工具栏"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"应用程序:layout_collapseMode="pin"app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/></android.support.design.widget.CollapsingToolbarLayout></android.support.design.widget.AppBarLayout><android.support.v4.widget.NestedScrollViewandroid:layout_width="match_parent"android:layout_height="wrap_content"app:layout_behavior="@string/appbar_scrolling_view_behavior"><线性布局android:id="@+id/linearLayout1"android:layout_width="match_parent"android:layout_height="match_parent"机器人:方向=垂直"><android.support.v7.widget.CardViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="@dimen/card_margin"><线性布局style="@style/Widget.CardContent"android:layout_width="match_parent"android:layout_height="wrap_content"><文本视图android:layout_width="match_parent"android:layout_height="wrap_content"机器人:文本=信息"android:textAppearance="@style/TextAppearance.AppCompat.Title"/><文本视图android:layout_width="match_parent"android:layout_height="wrap_content"android:text="@string/cheese_ipsum"/></LinearLayout></android.support.v7.widget.CardView></LinearLayout></android.support.v4.widget.NestedScrollView></android.support.design.widget.CoordinatorLayout>

和 CheeseDetailActivity.java:

public class CheeseDetailActivity extends AppCompatActivity {public static final String EXTRA_NAME = "cheese_name";私有最终上下文 mContext = this;私人 int screenHeight;私人 int linearLayoutHeight;私人 int toolbarHeight_org;私有 int 工具栏高度;@覆盖public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_detail);意图意图 = getIntent();final String cheeseName = intent.getStringExtra(EXTRA_NAME);screenHeight = getScreenHeight(this);TypedValue typedValue = new TypedValue();getTheme().resolveAttribute(R.attr.colorPrimary, typedValue, true);最终 int colorPrimary = typedValue.data;最终工具栏工具栏 = (工具栏) findViewById(R.id.toolbar);setSupportActionBar(工具栏);getSupportActionBar().setDisplayHomeAsUpEnabled(true);AppBarLayout appbar = (AppBarLayout) findViewById(R.id.appbar);final CoordinatorLayout.LayoutParams appbarLayoutParams = (CoordinatorLayout.LayoutParams)appbar.getLayoutParams();最终 ViewGroup.LayoutParams toolbarLayoutParams = toolbar.getLayoutParams();如果(工具栏布局参数!= null){toolbarHeight_org = toolbarLayoutParams.height;toolbarHeight = toolbarLayoutParams.height;}最终 CollapsingToolbarLayout collapsingToolbar =(CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);collapsingToolbar.setTitle(cheeseName);collapsingToolbar.setContentScrimColor(colorPrimary);collapsingToolbar.setExpandedTitleTextAppearance(R.style.ExpandedTitleTextAppearance);//collapsingToolbar.setCollapsedTitleTextAppearance(R.style.CollapsedTitleTextAppearance);final LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearLayout1);ViewTreeObserver 观察者 = linearLayout.getViewTreeObserver();观察者.addOnGlobalLayoutListener(新的ViewTreeObserver.OnGlobalLayoutListener(){@覆盖公共无效 onGlobalLayout() {linearLayoutHeight = linearLayout.getHeight();if (linearLayoutHeight + toolbarHeight < screenHeight) {如果(工具栏布局参数!= null){toolbarLayoutParams.height = screenHeight - linearLayoutHeight - 20;如果(toolbarLayoutParams.height < toolbarHeight_org){toolbarLayoutParams.height = toolbarHeight_org;}intextended_text_size = (int) getResources().getDimension(R.dimen.expanded_text_size);如果(appbarLayoutParams.height - toolbarLayoutParams.height <=extended_text_size){int value = appbarLayoutParams.height - toolbarLayoutParams.height;如果(值<0){appbarLayoutParams.height = toolbarLayoutParams.height - value + extended_text_size * 3;} 别的 {appbarLayoutParams.height = toolbarLayoutParams.height + extended_text_size * 3;}if (appbarLayoutParams.height >= screenHeight) {appbarLayoutParams.height = screenHeight;}}//collapsingToolbar.setContentScrimColor(getResources().getColor(android.R.color.transparent));如果 (toolbarLayoutParams.height > toolbarHeight_org) {collapsingToolbar.setContentScrimColor(ContextCompat.getColor(mContext, android.R.color.transparent));}}}//如果可能,移除监听器ViewTreeObserver viewTreeObserver = linearLayout.getViewTreeObserver();如果(viewTreeObserver.isAlive()){如果 (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {linearLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);} 别的 {linearLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);}}}});加载背景();appbar.setExpanded(true);}私有 int getScreenHeight(上下文上下文){int测量高度;点大小 = new Point();WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);如果 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {wm.getDefaultDisplay().getSize(size);测量高度 = size.y;} 别的 {显示 d = wm.getDefaultDisplay();测量高度 = d.getHeight();}返回测量高度;}私有无效负载背景(){最终 ImageView imageView = (ImageView) findViewById(R.id.backdrop);Glide.with(this).load(Cheeses.getRandomCheeseDrawable()).centerCrop().into(imageView);}@覆盖公共布尔 onCreateOptionsMenu(菜单菜单){getMenuInflater().inflate(R.menu.sample_actions, menu);返回真;}}

结果如下:

使用Cheesesquare 示例,我已经定制了这个项目并上传到我的GitHub.我同意它仍然存在一些问题,但是,至少它可以解决您的第一个问题.

请看一下.希望有帮助!

Background

I try to add the same functionality as shown on many apps, where the upper area of the screen shrinks&expands according to the scrolled content.

For this, I use Google's design library, as shown on the CheeseSquare sample.

The problem

Thing is, no matter how much content there is in the NestedScrollView , it lets me scroll way below the last view of the content, just to let me see the final state of the actionbar, having the minimal size of itself.

In short, this is what I see when scrolling to the bottom (modified content of CheeseSquare sample):

while this is what I'd like to have when scrolling to the bottom (taken from contacts app) :

I'm also trying to fix a bug on ThreePhasesBottomSheet sample that scrolling in the bottom sheet content is possible even when it's in peek-state. To reproduce, start scrolling horizontally (which doesn't do anything, as there is nothing to scroll this way) and then vertically, which would somehow trigger scrolling of the content of the bottom-sheet.

Therefore, I need to disable there the scrolling in "transformView()" method, in the case that "translation

This is how it works using normal usage:

And this is how it behaves with the bug of not blocking the scrolling:

What I've tried

I've tried to play with the "layout_scrollFlags" flags, to change the height to wrap_content, and to remove the clipToPadding and fitsSystemWindows attributes.

Here's the sample XML file, which I've modified to include only a single cardView instead of many:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    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="@dimen/detail_backdrop_height"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:fitsSystemWindows="true">

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

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

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

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

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

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:paddingTop="24dp">

            <android.support.v7.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/card_margin">

                <LinearLayout
                    style="@style/Widget.CardContent"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="Info"
                        android:textAppearance="@style/TextAppearance.AppCompat.Title" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@string/cheese_ipsum" />

                </LinearLayout>

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

        </LinearLayout>

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

    <android.support.design.widget.FloatingActionButton
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        app:layout_anchor="@id/appbar"
        app:layout_anchorGravity="bottom|right|end"
        android:src="@drawable/ic_discuss"
        android:layout_margin="@dimen/fab_margin"
        android:clickable="true"/>

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

I've tried the next code too :

((AppBarLayout.LayoutParams) collapsingToolbar.getLayoutParams()).setScrollFlags(0);

but this still allowed scrolling of the NestedScrollView itself in the CheeseSquare example, and also allowed flinging in the ThreePhasesBottomSheet sample .

The questions

  1. What can I do in order to make the scrolling stop when there is no more content to show at the bottom?

  2. In addition, what can be done to disable scrolling of the NestedScrollView in any time I wish ( for the ThreePhasesBottomSheet sample) ? Something like "setEnableScrolling(...)" ?

    I've tried to extend NestedScrollView and also extend from ScrollingViewBehavior, but failed to find what can be done to disable the scrolling.

It's probably a very simple thing to change, but I can't find out what...

EDIT: if needed, this is what I currently use for the design&support library

compile 'com.android.support:appcompat-v7:23.1.0'
compile 'com.android.support:design:23.1.0'


EDIT: for #2, I've found a workaround from within the BottomSheetLayout.java file, to disable all that's related to the variable "sheetViewOwnsTouch", as if it's always set to "false". This will allow stealing touch events on the bottom sheet. However, this is just a workaround, and only for this case. It also causes some touch events that should have been handled by other views. I still wish to know how to block the scrolling programmatically, and also in the other case of enough-space-to-show-content.

解决方案

What can I do in order to make the scrolling stop when there is no more content to show at the bottom?

Firstly, as I have commented below, the scrolling you said in your question is not of the NestedScrollView. It belongs to the CollapsingToolbarLayout. The NestedScrollView's scroll event only happens when CollapsingToolbarLayout fully collapsed, and of course it will stop scrolling when when there is no more content inside it (bottom reached). For the CollapsingToolbarLayout, it will collapse to its Toolbar's layout_height (as in the xml file, you will find "?attr/actionBarSize"). The following image will demonstrate that, pay attention to the red rectangular that is the toolbar (I set its background)

So to have a solution for your #1, you need to calculate the height of NestedScrollView, then if it's smaller than screen height, we fix the toolbar's height.

In short, you can update activity_detail.xml as the following:

<?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:id="@+id/main_content"
    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="@dimen/detail_backdrop_height"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

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

            <ImageView
                android:id="@+id/backdrop"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="false"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax" />

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

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

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

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"            
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:id="@+id/linearLayout1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <android.support.v7.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/card_margin">

                <LinearLayout
                    style="@style/Widget.CardContent"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="Info"
                        android:textAppearance="@style/TextAppearance.AppCompat.Title" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@string/cheese_ipsum" />

                </LinearLayout>

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

        </LinearLayout>

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

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

And CheeseDetailActivity.java:

public class CheeseDetailActivity extends AppCompatActivity {

    public static final String EXTRA_NAME = "cheese_name";
    private final Context mContext = this;
    private int screenHeight;
    private int linearLayoutHeight;
    private int toolbarHeight_org;
    private int toolbarHeight;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);

        Intent intent = getIntent();
        final String cheeseName = intent.getStringExtra(EXTRA_NAME);

        screenHeight = getScreenHeight(this);

        TypedValue typedValue = new TypedValue();
        getTheme().resolveAttribute(R.attr.colorPrimary, typedValue, true);
        final int colorPrimary = typedValue.data;

        final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        AppBarLayout appbar = (AppBarLayout) findViewById(R.id.appbar);
        final CoordinatorLayout.LayoutParams appbarLayoutParams = (CoordinatorLayout.LayoutParams)appbar.getLayoutParams();

        final ViewGroup.LayoutParams toolbarLayoutParams = toolbar.getLayoutParams();
        if (toolbarLayoutParams != null) {
            toolbarHeight_org = toolbarLayoutParams.height;
            toolbarHeight = toolbarLayoutParams.height;
        }

        final CollapsingToolbarLayout collapsingToolbar =
                (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
        collapsingToolbar.setTitle(cheeseName);

        collapsingToolbar.setContentScrimColor(colorPrimary);
        collapsingToolbar.setExpandedTitleTextAppearance(R.style.ExpandedTitleTextAppearance);
        //collapsingToolbar.setCollapsedTitleTextAppearance(R.style.CollapsedTitleTextAppearance);

        final LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearLayout1);
        ViewTreeObserver observer = linearLayout.getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                linearLayoutHeight = linearLayout.getHeight();
                if (linearLayoutHeight + toolbarHeight < screenHeight) {
                    if (toolbarLayoutParams != null) {
                        toolbarLayoutParams.height = screenHeight - linearLayoutHeight - 20;
                        if (toolbarLayoutParams.height < toolbarHeight_org) {
                            toolbarLayoutParams.height = toolbarHeight_org;
                        }

                        int extended_text_size = (int) getResources().getDimension(R.dimen.expanded_text_size);

                        if (appbarLayoutParams.height - toolbarLayoutParams.height <= extended_text_size) {
                            int value = appbarLayoutParams.height - toolbarLayoutParams.height;
                            if (value < 0) {
                                appbarLayoutParams.height = toolbarLayoutParams.height - value + extended_text_size * 3;
                            } else {
                                appbarLayoutParams.height = toolbarLayoutParams.height + extended_text_size * 3;
                            }
                            if (appbarLayoutParams.height >= screenHeight) {
                                appbarLayoutParams.height = screenHeight;
                            }
                        }

                        // collapsingToolbar.setContentScrimColor(getResources().getColor(android.R.color.transparent));
                        if (toolbarLayoutParams.height > toolbarHeight_org) {
                            collapsingToolbar.setContentScrimColor(ContextCompat.getColor(mContext, android.R.color.transparent));
                        }
                    }
                }
                // Removes the listener if possible
                ViewTreeObserver viewTreeObserver = linearLayout.getViewTreeObserver();
                if (viewTreeObserver.isAlive()) {
                    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                        linearLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    } else {
                        linearLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    }
                }
            }
        });

        loadBackdrop();
        appbar.setExpanded(true);
    }

    private int getScreenHeight(Context context) {
        int measuredHeight;
        Point size = new Point();
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
            wm.getDefaultDisplay().getSize(size);
            measuredHeight = size.y;
        } else {
            Display d = wm.getDefaultDisplay();
            measuredHeight = d.getHeight();
        }

        return measuredHeight;
    }

    private void loadBackdrop() {
        final ImageView imageView = (ImageView) findViewById(R.id.backdrop);
        Glide.with(this).load(Cheeses.getRandomCheeseDrawable()).centerCrop().into(imageView);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.sample_actions, menu);
        return true;
    }
}

Here's the result:

With Cheesesquare sample, I have customized this project and uploaded to My GitHub. I agree that it still has some problems, however, at least it can be a solution for your 1st issue.

Please take a look. Hope it helps!

这篇关于如何禁用 NestedScrollView&amp;CollapsingToolbarLayout 的滚动,例如当下面没有更多内容时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆