根据另一个 RV 滚动增加和减少 RV 高度
increasing and decreasing RV height depending on another RV scrolling
我想实现以下行为 -
https://ezgif.com/optimize/ezgif-6-66c61806b01c.gif
这是我的 XML 文件 -
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/fragment_marketplace_root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="7dp">
<LinearLayout
android:id="@+id/fragment_marketplace_main_linear_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
android:orientation="vertical">
<com.twoverte.views.ClearableAutoCompleteTextView
android:id="@+id/fragment_marketplace_searchview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="14dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="14dp"
android:completionThreshold="0"
android:hint="@string/fragment_marketplace_search_hint"
android:iconifiedByDefault="false"
android:inputType="text|textAutoCorrect"
android:maxLength="25"
android:textIsSelectable="false"
android:textSelectHandle="@xml/empty_shape"
tools:layout_editor_absoluteX="1dp"
tools:layout_editor_absoluteY="1dp" />
<TextView
android:id="@+id/fragment_marketplace_discover_products_from_myverte_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="14dp"
android:layout_marginTop="15dp"
android:fontFamily="@font/noto_sans"
android:text="@string/fragment_marketplace_discover_products_from_myverte"
android:textSize="17sp" />
<androidx.core.widget.NestedScrollView
android:id="@+id/fragment_marketplace_vendors_nested_scrollview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/fragment_marketplace_vendors_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="14dp"
android:layout_marginEnd="14dp"
android:orientation="horizontal"
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/fragment_marketplace_vendor_row_item" />
</androidx.core.widget.NestedScrollView>
<androidx.core.widget.NestedScrollView
android:id="@+id/fragment_marketplace_featured_products_nested_scroll_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/fragment_marketplace_featured_products_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/very_light_grey"
android:fontFamily="@font/noto_sans"
android:paddingStart="14dp"
android:paddingLeft="14dp"
android:paddingTop="15dp"
android:paddingEnd="14dp"
android:text="@string/fragment_marketplace_featured_products"
android:textSize="17sp"
android:visibility="gone"
tools:visibility="visible" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/fragment_marketplace_products_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="@color/very_light_grey"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
tools:listitem="@layout/fragment_marketplace_products_row_item" />
<View
android:id="@+id/activity_product_page_bottom_view"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginTop="60dp"
android:background="@color/light_black"
android:visibility="gone"
tools:visibility="visible" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
我已经尝试了很多 setOnScrollChangeListener
和 addOnScrollListener
的组合,但没有像预期的那样工作。
所需的结果是能够将最高 RV 增加和减少到一个上限。
向下滚动底部RV时应减少,向上滚动时应增加。
如果有人能帮我解决这个问题,我真的会亲吻他的腿,我花了很多时间试图破解如何让我厌倦这种行为。
编辑
所需的动画 -
我终于想通了。我将首先分享 XML 文件的代码,然后再解释所有相关内容。
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="256dp"
android:minHeight="132dp"
android:fitsSystemWindows="true"
app:titleEnabled="false"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<View
android:id="@+id/blue_view"
android:layout_width="match_parent"
android:layout_height="128dp"
android:background="@android:color/holo_blue_bright"
app:layout_collapseMode="pin"
app:layout_collapseParallaxMultiplier="0"
android:layout_gravity="top"/>
<HorizontalScrollView
android:id="@+id/pink_view"
android:layout_width="match_parent"
android:layout_height="128dp"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="1"
android:layout_gravity="bottom">
<View
android:layout_width="2000dp"
android:minWidth="2000dp"
android:layout_height="match_parent"
android:background="@color/colorAccent"/>
</HorizontalScrollView>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Note: I used View
with different colors in order to preview different segments in the Layout. I also used HorizontalScrollView
in order to showcase something like a RecyclerView
as in the gif you uploaded.
好的,首先,我们需要创建一个 CollapsingToolbarLayout
和 layout_scrollFlags
。
- 我们使用
scroll
必须启用标志才能使任何滚动效果生效
- 我们使用
snap
标志来确定当视图仅被部分缩小时要做什么。如果滚动结束并且视图大小已减小到其原始大小的 50% 以下,则此视图将 return 变为其原始大小。如果尺寸大于其尺寸的 50%,它将完全消失。
- 我们使用
exitUntilCollapsed
和 minHeight
来将 Toolbar
折叠成指定的 minHeight
我们希望 CollapsingToolbarLayout
具有:
layout_height
设置为 Toolbar
的 expanded 高度
minHeight
设置为 Toolbar
的 collapsed 高度
In this case, since we want the HorizontalScrollView
(pink_view
) only to get smaller in height, we set the minHeight
to the [ height of blue_view
+ smaller height of pink_view
]
Therefore, since blue_view
will remain 128dp
and we want pink_view
to go down to 4dp
, we set the minHeight
to 132dp
.
So here is a small example. Assume the blue_view
is like 100dp
and the pink_view
is initially 100dp
. So that's how we want it to show at first, but when I start scrolling we want the pink_view
to go down to 20dp
and the blue_view
will stay at 100dp
.
Therefore, layout_height
will be 200dp
and the minHeight
will be 120dp.
现在,我们希望 HorizontalScrollView
或 pink_view
折叠成 CollapsingToolbarLayout
高度 。
因此,我们将 layout_collapseMode="parallax"
添加到 pink_view
以便它与 CollapsingToolbarLayout
一起滚动。
layout_collapseParallaxMultiplier
决定图像的哪一部分(百分比)将隐藏在底部内容之下。在这里,我们希望它 all 被隐藏。因此,我们设置为1
.
与此同时,我们希望 blue_view
保持 固定 到顶部。而且我们也不希望它隐藏在任何底部内容下。
所以,我们将 layout_collapseMode="pin"
添加到 blue_view
,这样它就固定在 CollapsingToolbarLayout
的顶部。
我们还添加了 layout_collapseParallaxMultiplier="0"
以使其不被任何内容隐藏。
Please note that if the heights of the elements exceeds the minHeight
, the CollapsingToolbarLayout
will be pushed above the screen. It will then seem as if the height of the top item (here blue_view
) is decreasing in size.
预览:
这是另一个带有 RecyclerView
:
的演示
上面 RecyclerView
演示的 XML 如果有人感兴趣,请看下面。
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="256dp"
android:minHeight="148dp"
android:fitsSystemWindows="true"
app:titleEnabled="false"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<View
android:layout_width="match_parent"
android:layout_height="128dp"
android:background="@android:color/holo_blue_bright"
app:layout_collapseMode="pin"
app:layout_collapseParallaxMultiplier="0"
android:layout_gravity="top"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/hv_list"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="128dp"
android:minHeight="20dp"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="1"
android:layout_gravity="bottom"/>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
编辑:RecyclerViews 和 ViewHolders 的重要事项
要实现 RecyclerView
和 ViewHolder
的 高度 调整大小,我们必须在 offset
的 [=74] 时调整它们的大小=] 滚动变化。
This is because the CollapsingToolbarLayout
just scrolls the elements inside it under each other instead of actually resizing them.
因此,我们必须使用此处称为 hv_list
的 RecyclerView
和此处称为 app_bar
的 AppBarLayout
。
val hv_list: RecyclerView = findViewById(R.id.hv_list)
val app_bar: AppBarLayout = findViewById(R.id.app_bar)
之后,我们需要记住hv_list
的原始大小。
val hv_original_height: Int = hv_list.layoutParams.height
最后,我们需要为AppBarLayout
设置一个OffsetChangedListener
。在那里,我们将更改 RecyclerView
的 height,然后给它一个 margin bottom 以将其向上推 只因为它有重力底。
app_bar.addOnOffsetChangedListener(object : AppBarLayout.OnOffsetChangedListener {
override fun onOffsetChanged(appBarLayout: AppBarLayout, i: Int) {
hv_list.updateLayoutParams {
this.height = hv_original_height + i
(this as CollapsingToolbarLayout.LayoutParams).setMargins(0, 0, 0, abs(i))
}
}
})
Make sure that your itemView in the RecyclerView
has height of match_parent
我想实现以下行为 -
https://ezgif.com/optimize/ezgif-6-66c61806b01c.gif
这是我的 XML 文件 -
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/fragment_marketplace_root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="7dp">
<LinearLayout
android:id="@+id/fragment_marketplace_main_linear_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
android:orientation="vertical">
<com.twoverte.views.ClearableAutoCompleteTextView
android:id="@+id/fragment_marketplace_searchview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="14dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="14dp"
android:completionThreshold="0"
android:hint="@string/fragment_marketplace_search_hint"
android:iconifiedByDefault="false"
android:inputType="text|textAutoCorrect"
android:maxLength="25"
android:textIsSelectable="false"
android:textSelectHandle="@xml/empty_shape"
tools:layout_editor_absoluteX="1dp"
tools:layout_editor_absoluteY="1dp" />
<TextView
android:id="@+id/fragment_marketplace_discover_products_from_myverte_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="14dp"
android:layout_marginTop="15dp"
android:fontFamily="@font/noto_sans"
android:text="@string/fragment_marketplace_discover_products_from_myverte"
android:textSize="17sp" />
<androidx.core.widget.NestedScrollView
android:id="@+id/fragment_marketplace_vendors_nested_scrollview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/fragment_marketplace_vendors_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="14dp"
android:layout_marginEnd="14dp"
android:orientation="horizontal"
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/fragment_marketplace_vendor_row_item" />
</androidx.core.widget.NestedScrollView>
<androidx.core.widget.NestedScrollView
android:id="@+id/fragment_marketplace_featured_products_nested_scroll_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/fragment_marketplace_featured_products_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/very_light_grey"
android:fontFamily="@font/noto_sans"
android:paddingStart="14dp"
android:paddingLeft="14dp"
android:paddingTop="15dp"
android:paddingEnd="14dp"
android:text="@string/fragment_marketplace_featured_products"
android:textSize="17sp"
android:visibility="gone"
tools:visibility="visible" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/fragment_marketplace_products_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="@color/very_light_grey"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
tools:listitem="@layout/fragment_marketplace_products_row_item" />
<View
android:id="@+id/activity_product_page_bottom_view"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginTop="60dp"
android:background="@color/light_black"
android:visibility="gone"
tools:visibility="visible" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
我已经尝试了很多 setOnScrollChangeListener
和 addOnScrollListener
的组合,但没有像预期的那样工作。
所需的结果是能够将最高 RV 增加和减少到一个上限。
向下滚动底部RV时应减少,向上滚动时应增加。
如果有人能帮我解决这个问题,我真的会亲吻他的腿,我花了很多时间试图破解如何让我厌倦这种行为。
编辑
所需的动画 -
我终于想通了。我将首先分享 XML 文件的代码,然后再解释所有相关内容。
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="256dp"
android:minHeight="132dp"
android:fitsSystemWindows="true"
app:titleEnabled="false"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<View
android:id="@+id/blue_view"
android:layout_width="match_parent"
android:layout_height="128dp"
android:background="@android:color/holo_blue_bright"
app:layout_collapseMode="pin"
app:layout_collapseParallaxMultiplier="0"
android:layout_gravity="top"/>
<HorizontalScrollView
android:id="@+id/pink_view"
android:layout_width="match_parent"
android:layout_height="128dp"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="1"
android:layout_gravity="bottom">
<View
android:layout_width="2000dp"
android:minWidth="2000dp"
android:layout_height="match_parent"
android:background="@color/colorAccent"/>
</HorizontalScrollView>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Note: I used
View
with different colors in order to preview different segments in the Layout. I also usedHorizontalScrollView
in order to showcase something like aRecyclerView
as in the gif you uploaded.
好的,首先,我们需要创建一个 CollapsingToolbarLayout
和 layout_scrollFlags
。
- 我们使用
scroll
必须启用标志才能使任何滚动效果生效 - 我们使用
snap
标志来确定当视图仅被部分缩小时要做什么。如果滚动结束并且视图大小已减小到其原始大小的 50% 以下,则此视图将 return 变为其原始大小。如果尺寸大于其尺寸的 50%,它将完全消失。 - 我们使用
exitUntilCollapsed
和minHeight
来将Toolbar
折叠成指定的minHeight
我们希望 CollapsingToolbarLayout
具有:
layout_height
设置为Toolbar
的 expanded 高度
minHeight
设置为Toolbar
的 collapsed 高度
In this case, since we want the
HorizontalScrollView
(pink_view
) only to get smaller in height, we set theminHeight
to the [ height ofblue_view
+ smaller height ofpink_view
]Therefore, since
blue_view
will remain128dp
and we wantpink_view
to go down to4dp
, we set theminHeight
to132dp
.
So here is a small example. Assume the
blue_view
is like100dp
and thepink_view
is initially100dp
. So that's how we want it to show at first, but when I start scrolling we want thepink_view
to go down to20dp
and theblue_view
will stay at100dp
.Therefore,
layout_height
will be200dp
and theminHeight
will be 120dp.
现在,我们希望 HorizontalScrollView
或 pink_view
折叠成 CollapsingToolbarLayout
高度 。
因此,我们将 layout_collapseMode="parallax"
添加到 pink_view
以便它与 CollapsingToolbarLayout
一起滚动。
layout_collapseParallaxMultiplier
决定图像的哪一部分(百分比)将隐藏在底部内容之下。在这里,我们希望它 all 被隐藏。因此,我们设置为1
.
与此同时,我们希望 blue_view
保持 固定 到顶部。而且我们也不希望它隐藏在任何底部内容下。
所以,我们将 layout_collapseMode="pin"
添加到 blue_view
,这样它就固定在 CollapsingToolbarLayout
的顶部。
我们还添加了 layout_collapseParallaxMultiplier="0"
以使其不被任何内容隐藏。
Please note that if the heights of the elements exceeds the
minHeight
, theCollapsingToolbarLayout
will be pushed above the screen. It will then seem as if the height of the top item (hereblue_view
) is decreasing in size.
预览:
这是另一个带有 RecyclerView
:
的演示
上面 RecyclerView
演示的 XML 如果有人感兴趣,请看下面。
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="256dp"
android:minHeight="148dp"
android:fitsSystemWindows="true"
app:titleEnabled="false"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<View
android:layout_width="match_parent"
android:layout_height="128dp"
android:background="@android:color/holo_blue_bright"
app:layout_collapseMode="pin"
app:layout_collapseParallaxMultiplier="0"
android:layout_gravity="top"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/hv_list"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="128dp"
android:minHeight="20dp"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="1"
android:layout_gravity="bottom"/>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
编辑:RecyclerViews 和 ViewHolders 的重要事项
要实现 RecyclerView
和 ViewHolder
的 高度 调整大小,我们必须在 offset
的 [=74] 时调整它们的大小=] 滚动变化。
This is because the
CollapsingToolbarLayout
just scrolls the elements inside it under each other instead of actually resizing them.
因此,我们必须使用此处称为 hv_list
的 RecyclerView
和此处称为 app_bar
的 AppBarLayout
。
val hv_list: RecyclerView = findViewById(R.id.hv_list)
val app_bar: AppBarLayout = findViewById(R.id.app_bar)
之后,我们需要记住hv_list
的原始大小。
val hv_original_height: Int = hv_list.layoutParams.height
最后,我们需要为AppBarLayout
设置一个OffsetChangedListener
。在那里,我们将更改 RecyclerView
的 height,然后给它一个 margin bottom 以将其向上推 只因为它有重力底。
app_bar.addOnOffsetChangedListener(object : AppBarLayout.OnOffsetChangedListener {
override fun onOffsetChanged(appBarLayout: AppBarLayout, i: Int) {
hv_list.updateLayoutParams {
this.height = hv_original_height + i
(this as CollapsingToolbarLayout.LayoutParams).setMargins(0, 0, 0, abs(i))
}
}
})
Make sure that your itemView in the
RecyclerView
has height of match_parent