Android
ScrollView
User Interface
Layout Design
Mobile Development

Scrollview vertical and horizontal in android

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In classic Android views, ScrollView handles vertical scrolling and HorizontalScrollView handles horizontal scrolling. If a screen needs both directions, you usually nest one inside the other around a single child layout, but that choice works best for relatively small, static content.

Understand the Container Rules

Both ScrollView and HorizontalScrollView can have only one direct child. That child is usually a layout such as LinearLayout or ConstraintLayout.

A common pattern for two-direction scrolling is this:

xml
1<HorizontalScrollView
2    xmlns:android="http://schemas.android.com/apk/res/android"
3    android:layout_width="match_parent"
4    android:layout_height="match_parent"
5    android:fillViewport="true">
6
7    <ScrollView
8        android:layout_width="wrap_content"
9        android:layout_height="match_parent"
10        android:fillViewport="true">
11
12        <LinearLayout
13            android:layout_width="wrap_content"
14            android:layout_height="wrap_content"
15            android:orientation="vertical"
16            android:padding="16dp">
17
18            <TextView
19                android:layout_width="wrap_content"
20                android:layout_height="wrap_content"
21                android:text="Wide and tall content goes here" />
22
23        </LinearLayout>
24    </ScrollView>
25</HorizontalScrollView>

The outer HorizontalScrollView enables left and right movement. The inner ScrollView enables up and down movement. The inner child layout holds the actual content.

When This Layout Works Well

This approach is reasonable when you display content such as these:

  • a large comparison table
  • an oversized custom form
  • a generated report view
  • a diagram or matrix that does not recycle rows

It is not a good default for long, dynamic lists. If the content is list-shaped, use RecyclerView instead of putting many rows inside a ScrollView.

Programmatic Scrolling

You can also move the scroll position in code. For example, after layout you may want to jump to a specific offset:

kotlin
1val horizontal = findViewById<HorizontalScrollView>(R.id.horizontalScroll)
2val vertical = findViewById<ScrollView>(R.id.verticalScroll)
3
4horizontal.post {
5    horizontal.smoothScrollTo(200, 0)
6    vertical.smoothScrollTo(0, 300)
7}

The post call waits until the views have been measured. Without that, the requested coordinates may be applied too early.

Layout Sizing Matters

Many broken scroll layouts come from the wrong width and height values. For two-axis scrolling, the inner content usually needs wrap_content so it can grow beyond the viewport. If you force both axes to match_parent, the content may never become larger than the screen and there will be nothing to scroll.

Also watch fillViewport. It can be useful when the content is smaller than the screen and you still want it to expand to the viewport size. It does not create extra content space by itself.

Better Alternatives for Large Data

If you need a spreadsheet-like surface with many rows and columns, nested scroll containers can become sluggish. Consider a custom view, a specialized table widget, or a layout that recycles visible items.

For image panning and zooming, a nested ScrollView setup is also usually the wrong tool. A custom touch handler or a dedicated zoomable image component is more appropriate.

In other words, two-direction scrolling is valid, but it should match the content model. Do not use it just because the screen feels cramped.

Common Pitfalls

The first pitfall is adding multiple direct children to a ScrollView or HorizontalScrollView. Android expects exactly one direct child, so wrap multiple widgets in a layout container.

The second is nesting very large view hierarchies and then wondering why scrolling feels heavy. Scroll containers do not recycle child views. If the screen contains many repeated rows, switch to RecyclerView.

Another issue is scroll conflict. Nested containers can make touch handling feel awkward, especially when the content needs frequent diagonal gestures. Test the interaction on a real device, not only in the layout editor.

Finally, avoid putting scrolling containers inside other scrolling containers without a clear reason. That often produces confusing gesture behavior and hard-to-debug layout constraints.

Summary

  • 'ScrollView is vertical and HorizontalScrollView is horizontal'
  • For small static content that needs both axes, nest one around the other
  • Each scroll container can have only one direct child
  • Use wrap_content on inner content so the view can grow beyond the viewport
  • Prefer RecyclerView or a custom view for large or highly dynamic content

Course illustration
Course illustration

All Rights Reserved.