time

Working with the ScrollView in Android

Introduction

In this tutorial, you will learn to use Android ScrollView component in application. ScrollView is a different kind of layout than LinearLayout, RelativeLayout, etc. which is designed to view larger than its actual size. If the views inside ScrollView are more than the views that can be hold/contained within ScrollView then a scrollbar is automatically added.

ScrollView can hold only one direct child. This means that, if you have complex layout with more view controls, you must enclose them inside another standard layout like LinearLayout, TableLayout or RelativeLayout.

ScrollView only supports vertical scrolling. Use HorizontalScrollView for horizontal scrolling.

The android:fillViewport property defines whether the ScrollView should stretch its content to fill the viewport. You can set the same property by calling setFillViewport(boolean) method.

After creating the project, open the activity_main.xml file of your application from res/layout directory and replace the content with the content given below.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="wrap_content"
            android:layout_height="200dp"
            android:scaleType="centerCrop"
            android:src="@drawable/image" />        

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:padding="10dp"
            android:text="Android ScrollView Example"
            android:textStyle="bold" />    

    </LinearLayout>
</ScrollView>

Custom ScrollView

In android ScrollView there is no way or method to disable scrolling. But sometime it's necessary to disable scrolling of ScrollView while you are inside inner element, like if you want to disable ScrollView when you are inside Map view.

We can make our own ScrollView which have extra features for enable or disable scrolling.

public class ToggleScrollView extends ScrollView {
    private boolean enableScrolling = true;

    public ToggleScrollView(Context context) {
        super(context);
    }

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

    public ToggleScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public ToggleScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (scrollingEnabled()) {
            return super.onInterceptTouchEvent(ev);
        } else {
            return false;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (scrollingEnabled()) {
            return super.onTouchEvent(ev);
        } else {
            return false;
        }
    }
    private boolean scrollingEnabled(){
        return enableScrolling;
    }
    public void setScrolling(boolean enableScrolling) {
        this.enableScrolling = enableScrolling;
    }
}

Also create a layout with new ToggleScrollView.

<me.proft.projectA.ToggleScrollView
    android:id="@+id/svToggle"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- child views in here -->
</me.proft.projectA.ToggleScrollView>

So now you have embedded your own ScrollView. To disable scrolling just call setScrolling() method and pass true value. As shown in following example:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ToggleScrollView svToggle = (ToggleScrollView) findViewById(R.id.svToggle);
        svToggle.setScrolling(false); // to disable scrolling
        svToggle.setScrolling(true); // to enable scrolling
    }
}

Horizontally Scrolling

In other cases, we want content to horizontally scroll in which case we need to use the HorizontalScrollView instead like this:

<HorizontalScrollView
  android:layout_width="match_parent"
  android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >   
        <!-- child views in here -->
    </LinearLayout>
</HorizontalScrollView>

and now you have a horizontally scrolling view.

Scrollable TextView

Note that a TextView doesn't require a ScrollView and if you just need a scrolling TextView simply set the scrollbars property and apply the correct MovementMethod:

<TextView
    android:id="@+id/tv_long"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:scrollbars = "vertical"
    android:text="@string/really_long_string">
</TextView>

and then in the activity:

TextView tvTitle = (TextView) findViewById(R.id.tvTitle);
tvTitle.setMovementMethod(new ScrollingMovementMethod());

Now the TextView will automatically scroll vertically.

Nested ScrollViews

Adding a ScrollView within another ScrollView can be difficult. Most of the times it won’t end well. You will end up adding few workarounds. Instead, use the NestedScrollView as outlined here.

comments powered by Disqus