Android - 在CoordinatorLayout中使用时,页脚会滚动到屏幕之外

62

我有一个AppBarLayout,在滚动RecyclerView时,它会向上滚动并消失。 在RecyclerView下面有一个RelativeLayout作为页脚。

只有在向上滚动时,页脚才会显示出来 - 它的行为就像它有

layout_scrollFlags="scroll|enterAlways"

但它没有任何滚动标志-这是一个错误还是我做错了什么?我希望它始终可见。

滚动之前

enter image description here

滚动后

enter image description here

更新

在此问题上开了谷歌问题,被标记为“按预期工作”,但这仍然没有帮助,因为我想要一个在片段中的页脚的解决方案。

更新2

您可以在此处找到活动和片段xml文件 -

请注意,如果在activity.xml中的第34行注释掉包含app:layout_behavior="@string/appbar_scrolling_view_behavior"的行,则从一开始就可以看到文字end,否则只有在上滚后才能看到。


我浪费了半天的时间试图弄清楚发生了什么。感谢找到你的问题,我刚刚摆脱了CoordinatorLayout。现在一切都按预期工作了。 - Rafael
我有类似的问题,你能帮我吗: https://dev59.com/Pabja4cB1Zd3GeqPjqhb - chetan
9个回答

52

我使用了Learn OpenGL ES的简化版本solution -- 它对Noa的solution进行了改进。它可以很好地处理我的简单快速返回工具栏,该工具栏位于每个选项卡的ViewPager内容中,并带有页脚按钮。

只需将FixScrollingFooterBehavior设置为View/ViewGroup上的layout_behavior,即可使其保持与屏幕底部对齐。

布局:

<?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.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?android:attr/actionBarSize"
                android:minHeight="?android:attr/actionBarSize"
                app:title="Foo"
                app:layout_scrollFlags="scroll|enterAlways|snap"
                />

            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:tabMode="fixed"/>

    </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="com.spreeza.shop.ui.widgets.FixScrollingFooterBehavior"
        />

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

行为:

public class FixScrollingFooterBehavior extends AppBarLayout.ScrollingViewBehavior {

    private AppBarLayout appBarLayout;

    public FixScrollingFooterBehavior() {
        super();
    }

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

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {

        if (appBarLayout == null) {
            appBarLayout = (AppBarLayout) dependency;
        }

        final boolean result = super.onDependentViewChanged(parent, child, dependency);
        final int bottomPadding = calculateBottomPadding(appBarLayout);
        final boolean paddingChanged = bottomPadding != child.getPaddingBottom();
        if (paddingChanged) {
            child.setPadding(
                child.getPaddingLeft(),
                child.getPaddingTop(),
                child.getPaddingRight(),
                bottomPadding);
            child.requestLayout();
        }
        return paddingChanged || result;
    }


    // Calculate the padding needed to keep the bottom of the view pager's content at the same location on the screen.
    private int calculateBottomPadding(AppBarLayout dependency) {
        final int totalScrollRange = dependency.getTotalScrollRange();
        return totalScrollRange + dependency.getTop();
    }
}

6
非常感谢!我已经为此烦恼了一整天。 - Luke De Feo
1
@jhavatar,您能否在此处添加一些简要说明,解释一下这个自定义行为是如何工作的?它似乎运行得非常完美。 - PunitD
经过一年多的时间,当我的解决方案移动到支持库23时停止工作 - 使用了您的解决方案,现在它运行得很好。 - Noa Drach
你救了我的一天。 - Muklas
它运行良好,但是在底部留下了一个边距,该边距等于依赖项的初始大小getTop()。 - Usman Rana
显示剩余2条评论

18

我最初采用了Noa的解决方案(https://dev59.com/UF0a5IYBdhLWcg3wCE7P#31140112),这个方案对于手指拖动是有效的,但对于快速滑动则存在问题。经过一段时间的跟踪方法调用和尝试不同的想法,我最终得到了以下解决方案:

// Workaround for https://code.google.com/p/android/issues/detail?id=177195
// Based off of solution originally found here: https://dev59.com/UF0a5IYBdhLWcg3wCE7P#31140112
@SuppressWarnings("unused")
public class CustomScrollingViewBehavior extends AppBarLayout.ScrollingViewBehavior {
    private AppBarLayout appBarLayout;
    private boolean onAnimationRunnablePosted = false;

    @SuppressWarnings("unused")
    public CustomScrollingViewBehavior() {

    }

    @SuppressWarnings("unused")
    public CustomScrollingViewBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
        if (appBarLayout != null) {
            // We need to check from when a scroll is started, as we may not have had the chance to update the layout at
            // the start of a scroll or fling event.
            startAnimationRunnable(child, appBarLayout);
        }
        return super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
    }

    @Override
    public boolean onMeasureChild(CoordinatorLayout parent, final View child, int parentWidthMeasureSpec, int widthUsed,
                                  int parentHeightMeasureSpec, int heightUsed) {
        if (appBarLayout != null) {
            final int bottomPadding = calculateBottomPadding(appBarLayout);
            if (bottomPadding != child.getPaddingBottom()) {
                // We need to update the padding in onMeasureChild as otherwise we won't have the correct padding in
                // place when the view is flung, and the changes done in onDependentViewChanged will only take effect on
                // the next animation frame, which means it will be out of sync with the new scroll offset. This is only
                // needed when the view is flung -- when dragged with a finger, things work fine with just
                // implementing onDependentViewChanged().
                child.setPadding(child.getPaddingLeft(), child.getPaddingTop(), child.getPaddingRight(), bottomPadding);
            }
        }

        return super.onMeasureChild(parent, child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed);
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, final View child, final View dependency) {
        if (appBarLayout == null)
            appBarLayout = (AppBarLayout) dependency;

        final boolean result = super.onDependentViewChanged(parent, child, dependency);
        final int bottomPadding = calculateBottomPadding(appBarLayout);
        final boolean paddingChanged = bottomPadding != child.getPaddingBottom();
        if (paddingChanged) {
            // If we've changed the padding, then update the child and make sure a layout is requested.
            child.setPadding(child.getPaddingLeft(),
                    child.getPaddingTop(),
                    child.getPaddingRight(),
                    bottomPadding);
            child.requestLayout();
        }

        // Even if we didn't change the padding, if onDependentViewChanged was called then that means that the app bar
        // layout was changed or was flung. In that case, we want to check for these changes over the next few animation
        // frames so that we can ensure that we capture all the changes and update the view pager padding to match.
        startAnimationRunnable(child, dependency);
        return paddingChanged || result;
    }

    // Calculate the padding needed to keep the bottom of the view pager's content at the same location on the screen.
    private int calculateBottomPadding(AppBarLayout dependency) {
        final int totalScrollRange = dependency.getTotalScrollRange();
        return totalScrollRange + dependency.getTop();
    }

    private void startAnimationRunnable(final View child, final View dependency) {
        if (onAnimationRunnablePosted)
            return;

        final int onPostChildTop = child.getTop();
        final int onPostDependencyTop = dependency.getTop();
        onAnimationRunnablePosted = true;
        // Start looking for changes at the beginning of each animation frame. If there are any changes, we have to
        // ensure that layout is run again so that we can update the padding to take the changes into account.
        child.postOnAnimation(new Runnable() {
            private static final int MAX_COUNT_OF_FRAMES_WITH_NO_CHANGES = 5;
            private int previousChildTop = onPostChildTop;
            private int previousDependencyTop = onPostDependencyTop;
            private int countOfFramesWithNoChanges;

            @Override
            public void run() {
                // Make sure we request a layout at the beginning of each animation frame, until we notice a few
                // frames where nothing changed.
                final int currentChildTop = child.getTop();
                final int currentDependencyTop = dependency.getTop();
                boolean hasChanged = false;

                if (currentChildTop != previousChildTop) {
                    previousChildTop = currentChildTop;
                    hasChanged = true;
                    countOfFramesWithNoChanges = 0;
                }
                if (currentDependencyTop != previousDependencyTop) {
                    previousDependencyTop = currentDependencyTop;
                    hasChanged = true;
                    countOfFramesWithNoChanges = 0;
                }
                if (!hasChanged) {
                    countOfFramesWithNoChanges++;
                }
                if (countOfFramesWithNoChanges <= MAX_COUNT_OF_FRAMES_WITH_NO_CHANGES) {
                    // We can still look for changes on subsequent frames.
                    child.requestLayout();
                    child.postOnAnimation(this);
                } else {
                    // We've encountered enough frames with no changes. Do a final layout request, and don't repost.
                    child.requestLayout();
                    onAnimationRunnablePosted = false;
                }
            }
        });
    }
}

我不喜欢在每个动画帧上重新检查布局,而且这种解决方案并不完美,因为如果以编程方式展开/折叠应用栏布局,我曾经看到一些问题,但目前我没有找到更好的解决方案。在新设备上性能良好,在旧设备上也是可以接受的。如果有人找到更好的解决方案,请随时将我的答案作为来源并转载。


谢谢。这是我迄今为止找到的最佳解决方案。然而,它还不完美,因为它会产生闪烁效果。请参考http://stackoverflow.com/questions/36098350/how-to-fix-footer-properly-which-is-inside-coordinatorlayout以获取更多关于问题的解释。 - Cheok Yan Cheng
1
我找到了一种方法,可以隐藏工具栏而不影响页脚,而不使用CoordinatorLayout - http://stackoverflow.com/a/36122127/72437 - Cheok Yan Cheng
我试了你的解决方案。它起作用了。但是它在我的页脚下留下了额外的填充。无法找出原因。你有任何想法吗? - Midhun Vijayakumar
其他片段中也有额外的填充,并且没有页脚。 - Midhun Vijayakumar
1
花了几天时间获得50个声望,这样我就可以评论并感谢您的回答。这是正确的答案。另一个答案在许多情况下存在错误(离开片段然后返回等)。这解决了我所有与此问题相关的错误。 - rexar5
显示剩余2条评论

18

更新

以下方法不适用于5.1,与之前的版本不同,您需要在任何计算中使用getTranslationY而不是getTop

layout.getTop()-->(int)layout.getTranslationY()
appbar.getTop()+toolbar.getHeight()-->(int)(appbar.getTranslationY()+toolbar.getHeight())

更新2:新的支持库 - 22.2.1 - 与5.1和之前版本没有差异,您只需使用getTop并忽略此答案中的先前更新。

原始解决方案:在研究了许多方向后,结果证明解决方案实际上很简单-向片段添加paddingBottom并在页面滚动时进行调整。

需要填充以覆盖工具栏y位置的更改 - 协调布局将整个页面上移和下移,因为工具栏消失和重新出现。

这可以通过扩展AppBarLayout.ScrollingViewBehavior并将其设置为activityfragment元素的行为来实现。

以下是代码的基础知识 - 它适用于仅具有工具栏的活动 - 您可以将其替换为appbar.getTop() + toolbar.getHeight(),如果您的appbar包括tabs,则这将运作得更好。

activity.xml

<android.support.design.widget.CoordinatorLayout
android:id="@+id/main"
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.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:elevation="3dp"
    app:elevation="3dp">
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:layout_scrollFlags="scroll|enterAlways"
        />
</android.support.design.widget.AppBarLayout>
<fragment
    android:id="@+id/fragment"
    android:name="com.example.noa.footer2.MainActivityFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="com.example.noa.footer2.MyBehavior"
    tools:layout="@layout/fragment"/>
</android.support.design.widget.CoordinatorLayout>

fragment.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingBottom="48dp"
            android:background="@android:color/holo_green_dark"
            tools:context=".MainActivityFragment">
<android.support.v7.widget.RecyclerView
    android:id="@+id/list"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@null"/>
<View
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:layout_alignParentBottom="true"
    android:background="@android:color/holo_red_light"/>
</RelativeLayout>

MainActivityFragment#onActivityCreated


    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        CoordinatorLayout.LayoutParams lp = (LayoutParams) getView().getLayoutParams();
        MyBehavior behavior = (MyBehavior) lp.getBehavior();
        behavior.setLayout(getView());
    }

我的行为

public class MyBehavior extends AppBarLayout.ScrollingViewBehavior {

    private View layout;

    public MyBehavior() {
    }

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

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
        boolean result = super.onDependentViewChanged(parent, child, dependency);
        if (layout != null) {
            layout.setPadding(layout.getPaddingLeft(), layout.getPaddingTop(), layout
                .getPaddingRight(), layout.getTop());
        }
        return result;
    }

    public void setLayout(View layout) {
        this.layout = layout;
    }
}

2
在这一行代码上出现了类转换异常: CoordinatorLayout.LayoutParams lp = (LayoutParams) getView().getLayoutParams(); - Vihaan Verma
@VihaanVerma - 什么是异常? - Noa Drach
什么是用于强制转换 LayoutParams 的导入?当使用 CoordinatorLayout.LayoutParams 进行转换时,会针对相对布局(布局中的根视图)出现类转换异常。 - Vihaan Verma
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) pager.getLayoutParams(); - Noa Drach
2
很不幸,在动画期间出现了问题(当您滑动并让其动画展开/折叠工具栏时)。 - Learn OpenGL ES
显示剩余6条评论

1
package pl.mkaras.utils;

import android.content.Context;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.Toolbar;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;

public class ScrollViewBehaviorFix extends AppBarLayout.ScrollingViewBehavior {

    public ScrollViewBehaviorFix() {
        super();
    }

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

    public boolean onMeasureChild(CoordinatorLayout parent, View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec,
                                  int heightUsed) {
        if (child.getLayoutParams().height == -1) {
            List<View> dependencies = parent.getDependencies(child);
            if (dependencies.isEmpty()) {
                return false;
            }

            final AppBarLayout appBar = findFirstAppBarLayout(dependencies);
            if (appBar != null && ViewCompat.isLaidOut(appBar)) {
                int availableHeight = View.MeasureSpec.getSize(parentHeightMeasureSpec);
                if (availableHeight == 0) {
                    availableHeight = parent.getHeight();
                }

                final int height = availableHeight - appBar.getMeasuredHeight();
                int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.AT_MOST);

                parent.onMeasureChild(child, parentWidthMeasureSpec, widthUsed, heightMeasureSpec, heightUsed);
                int childContentHeight = getContentHeight(child);

                if (childContentHeight <= height) {
                    updateToolbar(parent, appBar, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed, false);

                    heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);
                    parent.onMeasureChild(child, parentWidthMeasureSpec, widthUsed, heightMeasureSpec, heightUsed);

                    return true;
                } else {
                    updateToolbar(parent, appBar, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed, true);

                    return super.onMeasureChild(parent, child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed);
                }
            }
        }

        return false;
    }

    private static int getContentHeight(View view) {
        if (view instanceof ViewGroup) {
            ViewGroup viewGroup = (ViewGroup) view;

            int contentHeight = 0;
            for (int index = 0; index < viewGroup.getChildCount(); ++index) {
                View child = viewGroup.getChildAt(index);
                contentHeight += child.getMeasuredHeight();
            }
            return contentHeight;
        } else {
            return view.getMeasuredHeight();
        }
    }

    private static AppBarLayout findFirstAppBarLayout(List<View> views) {
        int i = 0;

        for (int z = views.size(); i < z; ++i) {
            View view = views.get(i);
            if (view instanceof AppBarLayout) {
                return (AppBarLayout) view;
            }
        }

        throw new IllegalArgumentException("Missing AppBarLayout in CoordinatorLayout dependencies");
    }

    private void updateToolbar(CoordinatorLayout parent, AppBarLayout appBar, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec,
                               int heightUsed, boolean toggle) {
        toggleToolbarScroll(appBar, toggle);

        appBar.forceLayout();
        parent.onMeasureChild(appBar, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed);
    }

    private void toggleToolbarScroll(AppBarLayout appBar, boolean toggle) {
        for (int index = 0; index < appBar.getChildCount(); ++index) {
            View child = appBar.getChildAt(index);

            if (child instanceof Toolbar) {
                Toolbar toolbar = (Toolbar) child;
                AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) toolbar.getLayoutParams();
                int scrollFlags = params.getScrollFlags();

                if (toggle) {
                    scrollFlags |= AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL;
                } else {
                    scrollFlags &= ~AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL;
                }

                params.setScrollFlags(scrollFlags);
            }
        }
    }
}

这种行为基本上是从AppBarLayout中删除滚动标志SCROLL,当依赖视图(RecyclerViewNestedScrollView)中的滚动内容小于视图高度时,即不需要滚动时。它还覆盖了通常由AppBarLayout.ScrollingViewBehavior完成的偏移滚动视图的操作。在向滚动视图添加页脚(如按钮)或在ViewPager中使用时效果很好,因为每个页面的内容长度可能不同。

这个方法适用于工具栏中的scroll|enterAlways|snap scroll标志吗?我该如何让我的工具栏随着这种方法滚动? - Yuri Heupa
@YuriHeupa,它可以与其他滚动标志一起使用。这种方法只是删除或添加“SCROLL”标志,不会改变其他标志。当没有“SCROLL”标志时,其他标志将被忽略 - TrueCurry
尝试了这个解决方案。当视图数量少于滚动高度时,它可以正常工作,但如果项目移动,则根本无法滚动。这可能是在布局传递之后添加项目时发生的。 - Tejas Sherdiwala

0

将您的元素用LinearLayout包围起来,就像这样:

<android.support.design.widget.CoordinatorLayout >

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

    <android.support.design.widget.AppBarLayout>
      <android.support.v7.widget.Toolbar />
    </android.support.design.widget.AppBarLayout>
    <include layout="@layout/content_main" />

    </LinearLayout>

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

2
不要尝试这个答案,LinearLayout会阻止工具栏在滚动时折叠。正如官方文档(https://developer.android.com/reference/com/google/android/material/appbar/AppBarLayout)所解释的那样,AppBarLayout必须是CoordinatorLayout的直接子元素,否则它将无法工作。 - Ramiro G.M.

0

Android CoordinatorLayout底部布局行为示例

activity_bottom.xml

<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.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimaryDark"
            app:layout_scrollFlags="scroll|enterAlways"
            app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
    </android.support.design.widget.AppBarLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#C0C0C0"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <com.example.android.coordinatedeffort.widget.FooterBarLayout
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:layout_gravity="bottom">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="#007432"
            android:gravity="center"
            android:text="Footer View"
            android:textColor="@android:color/white"
            android:textSize="25sp" />
    </com.example.android.coordinatedeffort.widget.FooterBarLayout>

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

FooterBarLayout.java

FooterBarBehavior.java


0

我认为创建一个固定的页眉和页脚可以解决你的问题。我本来想在评论中写这个建议,但是我没有50个声望值。你可以在这里找到如何实现它。


谢谢,几天前这里有一个类似的答案被删除了(不是我),你提到的解决方案没有使用新的支持库。 - Noa Drach

0

我做了一些类似的事情,确保我在XML布局中添加了android:layout_gravity="end|bottom",以便将其放置在CoordinatorLayout底部。

然后在代码中设置:

 mRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @SuppressLint("NewApi")
        @SuppressWarnings("deprecation")
        @Override
        public void onGlobalLayout() {
            if (mFooterView != null) {
                final int height = mFooterView.getHeight();
                mRecyclerView.setPadding(0, 0, 0, height);
                mRecyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        }
    });

请注意:页脚的View/ViewGroup需要在z轴上更高(在XML中列在RecyclerView下方)才能正常工作。

这似乎有些不专业。 - wonsuc
1
此外,它在滚动视图底部添加了太多的填充,因此内容与页脚视图相距甚远。 - Gustavo Baiocchi Costa

-2

针对您的问题,有一个库可以解决。希望这真的能对您有所帮助。 这是该库的链接

另外,您提到的另一个问题是如何固定页脚。如果您的页脚使用相对布局,请在页脚上使用android:layout_alignParentBottom="true"特性。

希望我已经解决了您的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接