1. 程式人生 > Android入門教學 >Android 滾動條 ScrollView

Android 滾動條 ScrollView

到這裡基本上你已經掌握了 Android 所有的常用控制元件,不知道有沒有這樣的疑惑:如果控制元件太多,在有的小尺寸手機上將螢幕佔滿了怎麼辦?是不是有一種通用的解決方法?沒錯,本節的主角——ScrollView 就是來幫你解決這個問題的,它讓你的控制元件能夠在螢幕顯示不足的情況下,支援滾動展示。

1. ScrollView 的特性

ScrollView 是一種可以有效解決由於 View 過多顯示不全的佈局,它可以讓控制元件在橫向或者縱向上支援滾動顯示。它其實是一個 FrameLayout,內部可以包含一個或多個 View / ViewGroup,當然它的滾動效果也只會作用於子 View / ViewGroup 當中


另外需要注意的是因為它是一個 FrameLayout,所以我們需要注意它的佈局排列方式(對於 FrameLayout 的佈局方式可以參考第 11 節的內容),大多數場景下我們需要結合其他的佈局一起使用,其實最簡單的使用方式就是直接在寫好的佈局外面套一個 ScrollView 就可以支援滾動了
ScrollView 預設是縱向的滾動,如果需要橫向滾動可以使用HorizontalScrollView,只是方向不同,用法是完全一樣的。

注:對於需要支援滾動的場景而言,ScrollView 是一個非常完美的解決方案,但是我們後面會學到兩大滾動列表控制元件——ListView / GridView,因為這兩個控制元件天生就帶有滾動效果,所以通常我們不會將 ScrollView 和這兩個控制元件一起使用。

2. ScrollView 的基本用法

通常無論是控制元件還是佈局我們會先介紹屬性,但是 ScrollView 本質是一個 FrameLayout,作用也只是增加一個滾動效果,並沒有什麼很特別的屬性,這裡主要介紹一下幾個控制滾動的 API:

  • fullScroll():
    將列表滾動到頂部或者底部:ScrollView.FOCUS_DOWN 表示滾動到底部;ScrollView.FOCUS_UP 表示滾動到頂部。
  • scrollTo():
    將列表滾動到指定位置,引數為 x/y,分別表示橫縱座標的座標值。這裡要注意如果是縱向的 ScrollView,那麼橫座標(x)是無效的;相反橫向的 ScrollView,縱向(y)是無效的。

3. ScrollView 使用示例

ScrollView 的適用場景也很明顯,我們人為創造一個 View 過多的場景即可。

3.1 佈局檔案的編寫

首先佈局檔案主要包括 3 個部分:

  1. Button——用於點選回到頂部;
  2. Button——用於點選跳轉底部;
  3. ScrollView——包含過多的子 View,支援滾動。

然後我們將兩個用於跳轉的 Button 放入一個 LinearLayout 中,和 ScrollView 同層,這樣兩個 Button 就不會響應 ScrollView 的滑動,然後在 ScrollView 中新增一個 LinearLayout 用來管理需要滑動的 n 個 View,佈局檔案如下:

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

    <ScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="30dp">

        <LinearLayout
            android:id="@+id/button_group"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginTop="80dp"
                android:text="ScrollView"
                android:textSize="25dp"
                android:textStyle="bold" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginTop="20dp"
                android:text="Welcome to Imooc Android" />
            <!-- 在Java程式碼中動態新增若干個Button,超出螢幕範圍即可滑動 -->
        </LinearLayout>
    </ScrollView>

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

        <Button
            android:id="@+id/bt_to_top"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:text="滾動到頂部" />

        <Button
            android:id="@+id/bt_to_bottom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:text="跳轉到底部" />
    </LinearLayout>
</FrameLayout>

3.2 Java 檔案編寫

以上程式碼主要實現了兩個 Button 及一個 ScrollView,可以看到 ScrollView 中只有一個 LinearLayout,而 LinearLayout 中只有兩個 Button,所以我們需要在 Java 程式碼中動態新增 Button,這裡也可以讓大家熟悉一下如何動態建立並新增 Button。接下來在 Java 程式碼中主要做兩件事:

  • 為兩個 Button 設定點選事件,分別實現回到頂部及跳轉到底部;
  • 往 ScrollView 中新增 View,並繫結點選事件。

程式碼如下:

package com.emercy.myapplication;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.Toast;

public class MainActivity extends Activity implements View.OnClickListener {

    public static final int BUTTON_COUNT = 10;

    private ScrollView mScrollView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.bt_to_top).setOnClickListener(this);
        findViewById(R.id.bt_to_bottom).setOnClickListener(this);
        mScrollView = findViewById(R.id.scrollView);

        LinearLayout layout = findViewById(R.id.button_group);

        for (int i = 0; i < BUTTON_COUNT; i++) {
            Button button = new Button(this);
            LinearLayout.LayoutParams params =
                    new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            params.topMargin = 100;
            layout.addView(button, params);
            button.setOnClickListener(this);
            button.setText(i + "");
        }
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt_to_top:
                mScrollView.fullScroll(ScrollView.FOCUS_UP);
                break;
            case R.id.bt_to_bottom:
                mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
                break;
            default:
                Toast.makeText(this, "當前點選的是第" + ((Button) v).getText() + "個Button", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

效果如下:

ScrollView示例

我們在程式碼中通過 for 迴圈往 ScrollView 中添加了 10 個 Button,動態新增一個 View 主要有以下 4 步:

  1. 通過構造器建立 View。
  2. 設定其屬性(寬、高、margin、padding 等)。
  3. 設定響應事件(比如點選、觸控、滾動等)。
  4. 新增到相應的 ViewGroup 中。

我們在建立 Button 的同時通過setTextsetOnClickListener設定了文字及點選事件,然後在點選的時候展示當前 Button 的序號。

4. 小結

本節學習了一個新的 ViewGroup,它主要解決的就是當子 View 過多而導致螢幕顯示不下的問題。通過將過多的 View 放在一個 ScrollView 當中,系統會讓這些 View 支援列表滑動顯示,並提供了簡單的 API 幫助我們操作列表。對於需要橫向排列的 View 我們直接將 ScrollView 換成 HorizontalScrollView 即可,其他的使用方式完全一樣。

整體來說 ScrollView 是一種比較直接的實現列表的方式,優點是使用簡單,而且一目瞭然;缺點是資料和 UI 強耦合在一起,我們需要考慮的東西非常多,在實現複雜列表邏輯的時候會顯得很臃腫,這點在下一節以及後面學到 ListView / GridView 之後就會有深切的體會。