滾動條 ScrollView
到這里基本上你已經(jīng)掌握了 Android 所有的常用控件,不知道有沒有這樣的疑惑:如果控件太多,在有的小尺寸手機上將屏幕占滿了怎么辦?是不是有一種通用的解決方法?沒錯,本節(jié)的主角——ScrollView 就是來幫你解決這個問題的,它讓你的控件能夠在屏幕顯示不足的情況下,支持滾動展示。
1. ScrollView 的特性
ScrollView 是一種可以有效解決由于 View 過多顯示不全的布局,它可以讓控件在橫向或者縱向上支持滾動顯示。它其實是一個 FrameLayout,內(nèi)部可以包含一個或多個 View / ViewGroup,當然它的滾動效果也只會作用于子 View / ViewGroup 當中。
另外需要注意的是因為它是一個 FrameLayout,所以我們需要注意它的布局排列方式(對于 FrameLayout 的布局方式可以參考第 11 節(jié)的內(nèi)容),大多數(shù)場景下我們需要結(jié)合其他的布局一起使用,其實最簡單的使用方式就是直接在寫好的布局外面套一個 ScrollView 就可以支持滾動了。
ScrollView 默認是縱向的滾動,如果需要橫向滾動可以使用HorizontalScrollView
,只是方向不同,用法是完全一樣的。
注:對于需要支持滾動的場景而言,ScrollView 是一個非常完美的解決方案,但是我們后面會學到兩大滾動列表控件——ListView / GridView,因為這兩個控件天生就帶有滾動效果,所以通常我們不會將 ScrollView 和這兩個控件一起使用。
2. ScrollView 的基本用法
通常無論是控件還是布局我們會先介紹屬性,但是 ScrollView 本質(zhì)是一個 FrameLayout,作用也只是增加一個滾動效果,并沒有什么很特別的屬性,這里主要介紹一下幾個控制滾動的 API:
- fullScroll():
將列表滾動到頂部或者底部:ScrollView.FOCUS_DOWN
表示滾動到底部;ScrollView.FOCUS_UP
表示滾動到頂部。 - scrollTo():
將列表滾動到指定位置,參數(shù)為 x/y,分別表示橫縱坐標的坐標值。這里要注意如果是縱向的 ScrollView,那么橫坐標(x)是無效的;相反橫向的 ScrollView,縱向(y)是無效的。
3. ScrollView 使用示例
ScrollView 的適用場景也很明顯,我們?nèi)藶閯?chuàng)造一個 View 過多的場景即可。
3.1 布局文件的編寫
首先布局文件主要包括 3 個部分:
- Button——用于點擊回到頂部;
- Button——用于點擊跳轉(zhuǎn)底部;
- ScrollView——包含過多的子 View,支持滾動。
然后我們將兩個用于跳轉(zhuǎn)的 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代碼中動態(tài)添加若干個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="跳轉(zhuǎn)到底部" />
</LinearLayout>
</FrameLayout>
3.2 Java 文件編寫
以上代碼主要實現(xiàn)了兩個 Button 及一個 ScrollView,可以看到 ScrollView 中只有一個 LinearLayout,而 LinearLayout 中只有兩個 Button,所以我們需要在 Java 代碼中動態(tài)添加 Button,這里也可以讓大家熟悉一下如何動態(tài)創(chuàng)建并添加 Button。接下來在 Java 代碼中主要做兩件事:
- 為兩個 Button 設置點擊事件,分別實現(xiàn)回到頂部及跳轉(zhuǎn)到底部;
- 往 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 循環(huán)往 ScrollView 中添加了 10 個 Button,動態(tài)添加一個 View 主要有以下 4 步:
- 通過構造器創(chuàng)建 View。
- 設置其屬性(寬、高、margin、padding 等)。
- 設置響應事件(比如點擊、觸摸、滾動等)。
- 添加到相應的 ViewGroup 中。
我們在創(chuàng)建 Button 的同時通過setText
及setOnClickListener
設置了文本及點擊事件,然后在點擊的時候展示當前 Button 的序號。
4. 小結(jié)
本節(jié)學習了一個新的 ViewGroup,它主要解決的就是當子 View 過多而導致屏幕顯示不下的問題。通過將過多的 View 放在一個 ScrollView 當中,系統(tǒng)會讓這些 View 支持列表滑動顯示,并提供了簡單的 API 幫助我們操作列表。對于需要橫向排列的 View 我們直接將 ScrollView 換成 HorizontalScrollView 即可,其他的使用方式完全一樣。
整體來說 ScrollView 是一種比較直接的實現(xiàn)列表的方式,優(yōu)點是使用簡單,而且一目了然;缺點是數(shù)據(jù)和 UI 強耦合在一起,我們需要考慮的東西非常多,在實現(xiàn)復雜列表邏輯的時候會顯得很臃腫,這點在下一節(jié)以及后面學到 ListView / GridView 之后就會有深切的體會。