Androidアプリ開発 ViewPager paddingの仕様を理解する

2016年11月13日(編集2016年11月13日)
このエントリーをはてなブックマークに追加

Androidアプリ開発でViewPagerを使うと、スワイプで画面を切り替えるページを作成することができます。
しかし、Material DesignでViewPagerを利用する場合は、レイアウトの実装方法に注意が必要です。 この記事は、AndroidアプリのViewPagerの仕様を記載した記事です。

環境はAndroid 7.0 (API level 24) です。

環境

  • OS X Yosemite
  • Oracle jdk version 1.8.0_72
  • Android Studio 2.2.0
  • android sdk 24
  • support-v4 24.2.1

難易度

初心者向け

サンプルコード

Android-Material-Design-Demo

ViewPager

ViewPagerを使うと、スワイプで画面を切り替えるページを作成することができます。以下のようなページになります。

デフォルトViewPager

ScrollModeの仕様

ViewPagerは、ページの最初と最後で影を表示します。

この影はコードやxmlで表示/非表示を切り替えることができます。
xmlを使う場合は、以下のように変更します。

{project_folder}/res/layout/view_pager_activity.xml
        android:overScrollMode="never"
        

ビルドして表示します。

影を非表示

影が非表示になりました。

paddingの仕様

影の表示が必要な場合は、ViewPagerでpaddingを利用してはいけません。
paddingを設定すると影の位置がずれしまします。

例として、paddingTopを設定してみます。

{project_folder}/res/layout/view_pager_activity.xml
        android:paddingTop="50dp"
        

ビルドして表示します。

影がpadding分ずれたViewPager

あなたがAndroid開発に精通しているなら、android:clipToPaddingを利用して、paddingを無効にしようとするでしょう。
しかし、残念ながらViewPagerではandroid:clipToPaddingは効力がありません、
ライブラリのViewPagerのコードは以下のように実装されています。

https://github.com/android/platform_frameworks_support/blob/master/v4/java/android/support/v4/view/ViewPager.java#L2414
final int height = getHeight() - getPaddingTop() - getPaddingBottom();
// something
mLeftEdge.setSize(height, width);
        

高さからpadding値を引いた値が、影の高さとなっています。
なので、どうしてもpaddingの効力をなくす場合は、ViewPagerを継承したMyViewPagerクラスを作成してdrawメソッドをオーバーライドします。

{project_folder}/view/MyViewPager.java
public class MyViewPager extends ViewPager {


    public MyViewPager(Context context) {
        super(context);
    }

    public MyViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * 影のpaddingを無視したdraw
     *
     * @param canvas
     */
   +@Override
    public void draw(Canvas canvas) {
        int paddingLeft = getPaddingLeft();
        int paddingTop = getPaddingTop();
        int paddingRight = getPaddingRight();
        int paddingBottom = getPaddingBottom();
        super.setPadding(paddingLeft, 0, paddingRight, 0);
        super.draw(canvas);
        super.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
    }
}
        

これなら影の表示はpaddingの影響を受けません。しかし、コードよりもレイアウトの設計を見直すのが正しいアプローチ方法です。

まとめ

ViewPagerは便利なクラスです。
できれば、ViewPager側でpaddingを設定しないようにレイアウトを設計して使いましょう。

関連記事

タグ検索で調べてみよう

Android7.0 UI