This is an age old question, I'd try to answer it to the best of my understanding of the RecyclerView architecture.
For starters the two major types of scrolling are Horizontal and Vertical.
Vertical scrolling is done on Y axes and horizontal scrolling is done on X axes. The goal is to achieve scrolling on both axis (Y & X) which when combined is a 2D scroll.
Since 2D scrolling refers to the movement of content within a two-dimensional space, allowing users to view areas beyond the visible screen, the goal is to implement a 2D scroll in a vertically oriented RecyclerView
The repeated illustrations is typical example of a 2D scrollable layout
The most common way to achieve this is through wrapping the RecyclerView
in a HorizontalScrollView
as explained by the previous answers.
For this example:
In activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<HorizontalScrollView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:fillViewport="true">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:nestedScrollingEnabled="false"
android:id="@+id/recyclerview" />
</HorizontalScrollView>
</LinearLayout>
For the Item View Layout (e.g., list_item_log.xml root):
android:layout_height:
android:layout_width:
match_parent: Do not use. If set to match_parent, the item view would be forced to be only as wide as the RecyclerView's viewport. If you used a TextView as your list item, it would then wrap its text (if allowed) or clip it, and there would be nothing wider than the screen to scroll horizontally.
Wrapping a RecyclerView in a HorizontalScrollView
works but expect but expect trade-offs.
The second method is by using a RecyclerView.LayoutManager
Base on my understanding and test, creating a LinearLayoutManager (LLM)
is the best approach.
I can't answer this here because custom LLMs are complicated.
Check out my GitHub repository CodeOps Studio it's contains a module that implements an experimental LLM, i used to achieve 2D Scroll (if think it's cool leave a ⭐)
RecyclerView
wrapped in a HorizontalScrollView
to achieve 2D scroll.
Link: here
RecyclerView
with LLM to achieve 2D scroll
Link here:
Why Wrapping RecyclerView
in HorizontalScrollView
is Problematic because of the following
Measurement & Recycling Issues: RecyclerView
needs well-defined bounds (especially width, in this case) to know which items are visible and which can be recycled. When you place it inside a HorizontalScrollView
, the RecyclerView
might be measured with near-infinite width. This breaks its ability to efficiently determine which item views are off-screen vertically, potentially disabling view recycling altogether and causing massive performance degradation, negating the whole point of using RecyclerView
.
Touch Conflicts: Handling nested scrolling where one container scrolls horizontally and the child scrolls vertically can be very tricky to get right. You often end up with scenarios where either the horizontal or vertical scroll "wins" unexpectedly, leading to a poor user experience.
To anyone reading this I hope you find this helpful.
~ EUP