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 個部分:
- Button——用於點選回到頂部;
- Button——用於點選跳轉底部;
- 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;
}
}
}
效果如下:
我們在程式碼中通過 for 迴圈往 ScrollView 中添加了 10 個 Button,動態新增一個 View 主要有以下 4 步:
- 通過構造器建立 View。
- 設定其屬性(寬、高、margin、padding 等)。
- 設定響應事件(比如點選、觸控、滾動等)。
- 新增到相應的 ViewGroup 中。
我們在建立 Button 的同時通過setText
及setOnClickListener
設定了文字及點選事件,然後在點選的時候展示當前 Button 的序號。
4. 小結
本節學習了一個新的 ViewGroup,它主要解決的就是當子 View 過多而導致螢幕顯示不下的問題。通過將過多的 View 放在一個 ScrollView 當中,系統會讓這些 View 支援列表滑動顯示,並提供了簡單的 API 幫助我們操作列表。對於需要橫向排列的 View 我們直接將 ScrollView 換成 HorizontalScrollView 即可,其他的使用方式完全一樣。
整體來說 ScrollView 是一種比較直接的實現列表的方式,優點是使用簡單,而且一目瞭然;缺點是資料和 UI 強耦合在一起,我們需要考慮的東西非常多,在實現複雜列表邏輯的時候會顯得很臃腫,這點在下一節以及後面學到 ListView / GridView 之後就會有深切的體會。