2016年7月27日水曜日

Android CoordinatorLayoutのAnchor機能のまとめ

Android Design Support Library が提供する CoordinatorLayout は Google が推進している Material Design を実装するために、これまでの Layout と比べると幾つかの新しい機能を実装している。

その1つに Anchor 機能がある。これは CoordinatorLayout 内に配置される複数の子View の相対的な位置関係を指定する機能である。

幾つかの単語を定義する。

Anchor View

基準となるView。CoordinatorLayoutの子View、更にその下の階層のView等任意のViewがなれる。
但し、以下に定義する Anchored View 自身やその子、子孫Viewは Anchor View にはなれない。またCoordinatorLayout自身も Anchor View にはなれない。(Design Support Library 23.1 では CoordinatorLayout は Anchor View になれたが、23.2 又はそれ以上で確認したところ、IllegalStateException が発生するようになっていた。)

Anchored View

基準となるAnchor View に対し、相対的に位置関係を指定して配置される View。CoordinatorLayoutの直接の子Viewのみがなれる。これは Layout は一般的に自分の子Viewの配置のみを決めるためである。さらに下の階層での配置はその階層で決められる。

Design Support Library 以外のこれまでの View も Anchor View 及び Anchored View になれる。
また Anchor機能 は CoordinatorLayout が提供するもう1つの機能 Behavior とは無関係である。 但し Behavior にもレイアウト機能があるので、Behaviorが設定されていて、それがレイアウトを行う場合(より正確には Behavior#onLayoutChild が true を返した時)は Anchor での配置よりそちらが優先される。Behavoior の実装で Anchor を使用している場合もある。

Anchor View と Anchored View の指定はレイアウトファイルでおこなう。
以下は AndroidStudio で New Project を Scrolling Activity をテンプレートとして作成したファイル activity_scrolling.xml を一部抜粋、修正したものである。FloatingActionButton の代わりに普通の ImageButton を使用している。これは従来の普通の View で Anchor が設定できることを示すため。(なおコンパイルできるようにjavaソースコードも適当に変更している。)

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    <!-- 省略 -->
>

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        <!-- 省略 -->
    >
    </android.support.design.widget.AppBarLayout>

    <ImageButton
        <!-- 省略 -->
        app:layout_anchor="@id/app_bar"
        app:layout_anchorGravity="center_horizontal|bottom"
        android:layout_gravity="start|bottom"/>
</android.support.design.widget.CoordinatorLayout>

まず基準となる Anchor View には id をふっておく(android:id="@+id/app_bar")。
そして Anchored View となるViewで app:layout_anchor="@id/app_bar" と Anchor View を指定する。

次に Anchor View のどの場所を配置の基準とするかを app:layout_anchorGravity で決める。

left
基準点を Anchor View の左辺上にする。
right
基準点を Anchor View の右辺上にする。
center_horizontal
基準点を Anchor View の左右の中央にする。
top
基準点を Anchor View の上辺上にする。(指定しない場合のデフォルト値)
bottom
基準点を Anchor View の下辺上にする。
center_vertical
基準点を Anchor View の上下の中央にする。
start
配置の方向が左から右か、その逆かで基準点を Anchor View の左辺上または右辺上にする。(指定しない場合のデフォルト値)
end
配置の方向が左から右か、その逆かで基準点を Anchor View の右辺上または左辺上にする。
center
基準点を Anchor View の上下左右の中心にする。

この例だと app:layout_anchorGravity="center_horizontal|bottom" で基準点を Anchor View の左右中央で下辺上に設定している。

さらにこの基準点に対しどのように View を配置するかを android:layout_gravity で指定する。

left
基準点の左側に配置する。(上下の指定はあるが左右は指定しない場合のデフォルト値)
right
基準点の右側に配置する。
center_horizontal
基準点が View の左右の中心に来るように配置する。
top
基準点の上側に配置する。(左右の指定はあるが上下は指定しない場合のデフォルト値)
bottom
基準点の下側に配置する。
center_vertical
基準点が View の上下の中心に来るように配置する。
start
配置の方向が左から右か、その逆かで View を基準点の左側または右側に配置する。
end
配置の方向が左から右か、その逆かで View を基準点の右側または左側に配置する。
center
基準点が View の上下左右の中心に来るように配置する。(指定しない場合のデフォルト値)

この例では android:layout_gravity="start|bottom" で、基準点に対し左下側(左から右配置を仮定)に View を配置している。
但し、padding や margin も含めた範囲内から View がはみ出る場合はその分移動させられ、強制的に枠内に収まるように配置される。

以下は例に上げたレイアウトファイルの場合の画面。

0 件のコメント:

コメントを投稿