marunomaruno-memo

marunomaruno-memo

[Android] コンテナ (2) スクロール表示 - ScrollView、HorizontalScrollView

2012年03月26日 | Android
[Android] コンテナ (2) スクロール表示 - ScrollView、HorizontalScrollView
================================================================================

ScrollView は、そのコンテンツのスクロール機能を提供するコンテナ。画面に入りきれ
ないと思われるウィジェットを ScrollView で囲むことで、既存のレイアウトをそのまま
使うことができる。

使い方としては以下のとおり。
    <ScrollView>
        他のウィジェット
    </ScrollView>


ScrollView は、縦スクロール。HorizontalScrollView は横スクロールが可能になる。
縦と横の両方を可能にするためには、ScrollView と HorizontalScrollView とを組み合
わせればよい。すなわち、次のような形になる。
    <HorizontalScrollView>
        <ScrollView>
            他のウィジェット
        </ScrollView>
    </HorizontalScrollView>


▲ レイアウト

同じレイアウトに対して、つぎの 3 つのパターンを表示。

    ScrollView
    HorizontalScrollView
    ScrollView と HorizontalScrollView の組合わせ

レイアウトは、TableLayout01 のサンプル。
したがって、拡大していくと、それぞれが縦スクロール、横スクロール、縦横スクロール
ができる。

わかりやすくするために、ScrollView 要素に囲まれているウィジェットは、table.xml 
をインクルードしている。

□ res/layout/main.xml
---
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ScrollView"
        android:textAppearance="?android:attr/textAppearanceLarge" />
    
    <ScrollView
        android:id="@+id/scrollView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" >

        <include android:id="@+id/table0" layout="@layout/table" />
    </ScrollView>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="HorizontalScrollView"
        android:textAppearance="?android:attr/textAppearanceLarge" />
        
    <HorizontalScrollView
        android:id="@+id/horizontalScrollView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" >

        <include android:id="@+id/table1" layout="@layout/table" />
    </HorizontalScrollView>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="HorizontalScrollView + ScrollView"
        android:textAppearance="?android:attr/textAppearanceLarge" />
        
    <HorizontalScrollView
        android:id="@+id/horizontalScrollView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" 
        android:scrollbars="none">

        <ScrollView
            android:id="@+id/scrollView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" 
            android:scrollbars="none">

            <include android:id="@+id/table2" layout="@layout/table" />
        </ScrollView>
    </HorizontalScrollView>

</LinearLayout>
---


□ ScrollView クラス

java.lang.Object
   +   android.view.View
        +   android.view.ViewGroup
             +   android.widget.FrameLayout
                  +   android.widget.ScrollView

ScrollView は、そのコンテンツの縦スクロール機能を提供するコンテナ。


XML 属性(属性名の前に、名前空間プレフィックス android: がつく)
---
fillViewport  子のウィジェットが小さい場合でも、このビューの高さ分の領域をとる
---

setFillViewport(boolean) メソッドにより、属性値を動的に変更できる。


□ HorizontalScrollView

java.lang.Object
   +   android.view.View
        +   android.view.ViewGroup
             +   android.widget.FrameLayout
                  +   android.widget.HorizontalScrollView

HorizontalScrollView は、そのコンテンツの横スクロール機能を提供するコンテナ。


XML 属性(属性名の前に、名前空間プレフィックス android: がつく)
---
fillViewport  子のウィジェットが小さい場合でも、このビューの幅分の領域をとる
---

setFillViewport(boolean) メソッドにより、属性値を動的に変更できる。


・スクロールバーの表示

android:scrollbars 属性は、スクロールバーを表示するかしないかを指定する。
つぎの値が指定できる。
    none          スクロールが必要になっても表示しない
    horizontal    横スクロールが必要なときに横バーを表示
    vertical      縦スクロールが必要なときに縦バーを表示

なお、ScrollViewで、実際にスクロールバーが表示されるのは、スクロールが必要なとき
で、android:scrollbars="vertical" と指定しても、最初からスクロールバーが表示され
るわけではない。表示させたくないときは値 "none" を指定する。


□ res/layout/table.xml

※ TableLayout01 プロジェクトの res/layout/main.xml と同じ。


▲ アクティビティ

ボタンがクリックされたら、その状態によって、ボタンの幅と高さを倍にするか半分にす
る。

□ ScrollView01Activity.java

※ クラス名が上記の名前になっているだけで、コードは LinearLayout01Activity.java と同じ。


■ 実例

サンプルのプロジェクトは、以下の記事を参照。
    SystemOut01 プロジェクト
    標準出力 - あて先に画面を追加する, 2011-12-22
    http://blog.goo.ne.jp/marunomarunogoo/d/20111222

System.out を TextView に割り当て、いかにもコンソールに出力するように、表示部分
がスクロールするようにしているサンプルである。


▲ レイアウト

レイアウトだけ再掲載する。

□ res/layout/main.xml

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

    <ScrollView
        android:id="@+id/sysoutScrollView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >    <!-- (1) -->

        <TextView
            android:id="@+id/sysout"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />    <!-- (2) -->
    </ScrollView>

</LinearLayout>
---

ScrollView 要素の下に TextView 要素。この TextView が画面いっぱいになったら、ス
クロール・バーが表示される。


■ 自動スクロールダウン

ScrollView を使っただけでは、自動的にスクロールダウンしない。自動的にスクロール
ダウンさせるのであれば、以下のようなスレッドを作り、ポストする。

上記の例であれば、
        TextView view = (TextView) findViewById(R.id.sysout);
としたときに、

    ((View) view.getParent()).post(new ScrollDown());

で、スクロール・ダウンさせるスレッドを設定する。

スクロール・ダウンさせるスレッドは、以下のように作成する。
なお、view は、インスタンス・フィールドか、final ローカル変数として定義してある
ものとする。

---
    /**
     * スクロールダウンさせるスレッドのクラス
     * @author marunomaruno
     */
    private class ScrollDown implements Runnable { // (8)
        public void run() {
            ((ScrollView) view.getParent()).fullScroll(View.FOCUS_DOWN); // (9)
        }
    }
---

                                                                            以上