当与viewpager和recyclerview一起使用时,CollapsingToolbarLayout的部分内容在顶部变得发粘 [英] Part of the content of a CollapsingToolbarLayout is getting sticky on top, when used with viewpager and recyclerview

本文介绍了当与viewpager和recyclerview一起使用时,CollapsingToolbarLayout的部分内容在顶部变得发粘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现这样的布局:

I am trying to implement a layout like this:

问题在于,向上滚动卡时,它会触摸工具栏,并且不再像这样上升:

The issue is that when scrolling up the card touches the toolbar and it does not go up anymore like this:

我希望它向上滚动直到viewpager填满屏幕,即至少矩形卡应该向上滚动到工具栏之外(即使tabLayout也可以向上滚动).但是我不希望它在顶部保持粘性.

I want it to scroll up till the viewpager to fills the screen ie, at least the rectangle card, should scroll up beyond the toolbar(Even the tabLayout can also scroll up). But I don't want it to stay sticky at the top.

主要布局在这里:

 <?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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"
    tools:showIn="@layout/activity_main">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/background_dark"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/toolbarCollapse"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="190dp"
                android:minHeight="190dp"
                android:src="@drawable/ic_launcher_foreground"
                app:layout_collapseMode="parallax" />


            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?actionBarSize"
                app:layout_collapseMode="pin" />

        </com.google.android.material.appbar.CollapsingToolbarLayout>


    </com.google.android.material.appbar.AppBarLayout>


    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        app:behavior_overlapTop="90dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:id="@+id/lin"
            android:nestedScrollingEnabled="false"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <include layout="@layout/debit_card_item" />


            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="?actionBarSize"
                android:layout_marginTop="40dp"
                android:background="?attr/colorPrimary" />


            <androidx.viewpager.widget.ViewPager
                android:id="@+id/viewPager"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1" />

        </LinearLayout>
    </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

分页器的片段在NestedScrollView中,如下所示:

The fragments of the pager are inside a NestedScrollView like this:

<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rcView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</androidx.core.widget.NestedScrollView>

我尝试过的事情:

  1. 我尝试删除线性布局上方的NestedScrollView,并将app:behavior_overlapTop="90dp" app:layout_behavior="@string/appbar_scrolling_view_behavior"添加到线性布局.但它仍然给我相同的输出.
  2. 静态设置视图寻呼机的高度(具有相同的结果).
  1. I have tried to remove the NestedScrollView above the linear layout and added the app:behavior_overlapTop="90dp" app:layout_behavior="@string/appbar_scrolling_view_behavior" to the linear layout. but it's still giving me the same output.
  2. Set the height of the view pager statically(gave the same result).

->>> EDIT<<< 3.我想到了一种解决方法,我试图在mainActivity中将自定义行为添加到LinearLayout中.从而减少矩形卡的底边和高度.当我猛扑并关闭折叠的工具栏时,它会提供良好的效果.但是当我按住并滚动时,屏幕闪烁,如下所示:

-->>>EDIT<<< 3. I thought of a workaround and I am trying to add custom behavior to my LinearLayout in my mainActivity. so as to reduce the margin-bottom and height of the rectangular card. It is giving good results when I fling and close the collapsing toolbar. But when I hold down and scroll, the screen is flickering as shown below:

我的自定义行为是

class CustomHeaderBehavior : AppBarLayout.ScrollingViewBehavior {
    private var mContext: Context

    var height = 0
    var width = 0
    var marginBottom = 0
    var firstTime = true

    constructor(
        context: Context,
        attrs: AttributeSet?
    ) : super(context, attrs) {
        mContext = context
    }

    constructor(
        context: Context?,
        attrs: AttributeSet?,
        mContext: Context
    ) : super(context, attrs) {
        this.mContext = mContext
    }

    override fun layoutDependsOn(
        parent: CoordinatorLayout,
        child: View,
        dependency: View
    ): Boolean {
        return super.layoutDependsOn(parent, child, dependency)
    }

    override fun onDependentViewChanged(
        parent: CoordinatorLayout,
        childP: View,
        dependency: View
    ): Boolean {
        val child = childP.findViewById<RelativeLayout>(R.id.cardParent)
        val maxScroll: Int = (dependency as AppBarLayout).totalScrollRange
        val percentage =
            abs(dependency.y) / maxScroll.toFloat()
        Log.d("Behavx","D.y "+abs(dependency.y)+ " m s "+maxScroll+ " p "+percentage)
        val lp: LinearLayout.LayoutParams =
            child.layoutParams as LinearLayout.LayoutParams
        if(firstTime){
            height = child.height
            width = child.width
            marginBottom = lp.bottomMargin
            firstTime = false
        }
        Log.d("Behaviour", "P "+ ((1-(percentage))*100).toString() +" H " +height+ " U H " +(height*(((1-(percentage))*100))/100) )
//        lp.bottomMargin = ((marginBottom*(((1-(percentage))*100))/100) - ((height*((((percentage))*100))/100))).toInt()
        lp.bottomMargin = ((marginBottom*(((1-(percentage))*100))/100)).toInt() //updating margin bottom
        lp.height = ((height*(((1-(percentage))*100))/100)).toInt() //updating height

        child.layoutParams = lp
        child.alpha = 1 - (percentage * 4)
        return super.onDependentViewChanged(parent, childP, dependency)

    }


    companion object {
        fun getToolbarHeight(context: Context): Int {
            var result = 0
            val tv = TypedValue()
            if (context.theme.resolveAttribute(R.attr.actionBarSize, tv, true)) {
                result = TypedValue.complexToDimensionPixelSize(
                    tv.data,
                    context.resources.displayMetrics
                )
            }
            return result
        }
    }
}

闪烁似乎是由于dependency.y随机出错而引起的,而我按住并滚动并更新了卡的高度(如果我只更新了边距闪烁,则不会发生).由于某种原因,宽度控制无法顺利进行.不幸的是,这对我没有帮助.

The flicker seems to be happening because the dependency.y is becoming wrong randomly, while I hold down and scroll and update the height of the card(if I only update the margin flicker is not occurring). For some reason controlling the width is happening smoothly. But unfortunately, that's not helping me here.

  1. 我还尝试通过向应用栏中添加offsetChangedListener来执行类似的操作:

appBar.addOnOffsetChangedListener(OnOffsetChangedListener {appBarLayout,verticalOffset-> 如果(abs(verticalOffset)== appBarLayout.totalScrollRange){ //收合 cardParent.visibility = View.GONE } 别的 { //展开 cardParent.visibility = View.VISIBLE } })

appBar.addOnOffsetChangedListener(OnOffsetChangedListener { appBarLayout, verticalOffset -> if (abs(verticalOffset) == appBarLayout.totalScrollRange) { // Collapsed cardParent.visibility = View.GONE } else { //Expanded cardParent.visibility = View.VISIBLE } })

但是我仍然忽隐忽现

我在这里添加了示例项目: github链接 自定义行为被推送到新的分支custom_behaviour

I have added the sample project here: github link The custom behavior is pushed to a new branch custom_behaviour

推荐答案

最终解决了我的问题.我将卡添加到了像Kalyans answer 之类的折叠布局中,并向卡中添加了虚拟视图和-ve边距重叠行为效果

Finally Solved my issue. I added the card inside the collapsing layout like Kalyans answer and added a dummy view and a -ve margin to the card to have the overlap behavior effect like

<com.google.android.material.appbar.CollapsingToolbarLayout
        android:id="@+id/toolbarCollapse"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        app:contentScrim="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

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

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?actionBarSize"
            app:layout_collapseMode="pin" />

        <View
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="#000" />

        <include
            layout="@layout/debit_card_item"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="-90dp"
            app:layout_collapseMode="parallax" />
    </LinearLayout>

</com.google.android.material.appbar.CollapsingToolbarLayout>

我也将代码推送到了github.

I have also pushed my code to the github.

这篇关于当与viewpager和recyclerview一起使用时,CollapsingToolbarLayout的部分内容在顶部变得发粘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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