LoginSignup
11
10

More than 5 years have passed since last update.

Google Play ストアのトップページのUIを考察してみた

Last updated at Posted at 2018-04-04

はじめに

Qiita初投稿です。ここ1年はAndroidをメインでやってます。
マテリアルデザインを勉強していて、PlayストアのUIがいい感じだったので、構成を考察してみました。
(個人的な考察なので、実際のところはわかりません。)

  • Playストアのバージョン 9.4.18

PlayStore.png

(2018/04/17 更新)

  • GitHubにサンプルアプリのソースをあげました
  • こんな感じに動きます

material_ui_sample.gif

前提条件

  • Android Studio 3.1.0
  • targetSdkVersion 27
  • minSdkVersion 21
  • compileSdkVersion 27

レイアウト構成

DrawerLayout + NavigationView

  • 基本的なナビゲーションドロワーの構成

CoordinatorLayout + AppBarLayout

  • この構成により、コンテンツ部分のスクロールと連動してToolbarが隠れるようになっています

TabLayout + ViewPager

  • メインのコンテンツ部分は基本的なタブの構成
  • ポイントはタブ選択時のアニメーション
    • Revealと呼ばれるもので、詳細は後述します
    • カテゴリごとにヘッダー部分の色が変化します

SearchView + AnimatedVectorDrawable

  • 検索バーの部分
  • ポイントは検索バーにフォーカスが当たるとメニューアイコンがアニメーションするところ
  • AnimatedVectorDrawableを使えば簡単にできそう

icon.gif

実装方法について

ヘッダー部分のReveal

概要

  • タブ選択時にAppBarLayoutの背景色がRevealというアニメーションで切り替わるようになっています
  • Revealはユーザーがタップした時に波紋状に広がるアニメーションのことです

考察

  • ステータスバーの部分も綺麗にアニメーションしていたので、ステータスバーを透過させてるのかと思ったのですが、コンテンツをスクロールするとToolbarがステータスバーの下に隠れてるので、透過ではなさそう。。。
  • AppBarLayoutとステータスバーの部分で2つアニメーション用のViewがあればできそう

実装方法

  • AppBarLayoutとステータスバーは透過させて、それぞれのアニメーション用のViewと背景用のViewを用意すればできます
  • アニメーションの起点はタブにCustomViewを設定して、そこから計算できそう
  • イケてないかもしれませんが、こんなレイアウト構成なら実装できました
<DrawerLayout>
  <CoordinatorLayout>
    <FrameLayout>
      <View/> <!-- AppBarLayoutのアニメーション時の背景用 -->
      <View/> <!-- AppBarLayoutのアニメーション用 -->
    </FrameLayout>
    <AppBarLayout>
      <Toolbar/>
      <TabLayout/>
    </AppBarLayout>
    <FrameLayout>
      <View/> <!-- ステータスバーのアニメーション時の背景用 -->
      <View/> <!-- ステータスバーのアニメーション用 -->
    </FrameLayout>
    <ViewPager/>
  </CoordinatorLayout>
  <NavigationView/>
</DrawerLayout>
  • アニメーションの実装はViewAnimationUtils.createCircularReveal()を使えば簡単にできます。
  • 複数アニメーションはAnimatorSetでまとめると良いです
private View reveal;          // Reveal用のView(AppBarLayout)
private View statusReveal;    // Reveal用のView(ステータスバー)
private View bgReveal;        // アニメーション中の背景用(AppBarLayout)
private View bgStatusReveal;  // アニメーション中の背景用(ステータスバー)

/**
 * Revealの開始
 * @param position 選択したタブのposition
 * @param centerX アニメーション起点のX座標
 * @param centerY アニメーション起点のY座標
 */
private void startReveal(int position, int centerX, int centerY) {
  // タブのpositionから色を取得
  final @ColorRes int colorResId = getTabColorAtPosition(position);
  final float radius = Math.max(reveal.getWidth(), reveal.getHeight()) * 1.2f;

  reveal.setBackgroundResource(colorResId);
  statusReveal.setBackgroundResource(colorResId);

  AnimatorSet animatorSet = new AnimatorSet();
  animatorSet.setDuration(500);
  animatorSet.playTogether(
    ViewAnimationUtils.createCircularReveal(reveal, centerX, centerY, 0, radius),
    ViewAnimationUtils.createCircularReveal(statusReveal, centerX, centerY, 0, radius));
  animatorSet.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
      super.onAnimationEnd(animation);
      bgReveal.setBackgroundResource(colorResId);
      bgStatusReveal.setBackgroundResource(colorResId);
    }
  });
  animatorSet.start();
}

コンテンツスクロール時にToolbarを隠す

概要

  • スクロールと連動して、Toolbarなどを隠したり、小さくしたりできます

考察

  • Toolbarだけならlayout_scrollFlagsにオプションをセットすればできます
  • Reveal用に独自のViewを用意したので、それら用にBehaviorを実装する必要があります

実装方法

  • CoordinatorLayout.Behaviorを使えばViewに対しての振る舞いを実装できます
  • Behaviorは以下のようなシンプルな実装で十分です
public class HeaderBehavior extends CoordinatorLayout.Behavior<View> {
  private int defaultDependencyTop = -1;

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

  @Override
  public boolean layoutDependsOn(CoordinatorLayout parent, View view, View dependency) {
    return dependency instanceof AppBarLayout;
  }

  @Override
  public boolean onDependentViewChanged(CoordinatorLayout parent, View view, View dependency) {
    if (defaultDependencyTop == -1) {
      defaultDependencyTop = dependency.getTop();
    }
    view.setTranslationY(dependency.getTop() - defaultDependencyTop);
    return true;
  }
}
  • レイアウトのxmlで以下のように設定します
<CoordinatorLayout>
  <FrameLayout app:layout_behavior="com.XXX.XXX.HeaderBehavior" />
  <Toolbar app:layout_scrollFlags="scroll|enterAlways" />
  <TabLayout/>
  <FrameLayout/>
</CoordinatorLayout>

検索バーのアイコン

概要

  • 検索バーをタップした時にアイコンがアニメーションして別のアイコンに切り替わります
  • 2つの機能をトグルのようにアニメーションで切り替えるのが主流のようです
  • Creative customization - Iconsに記載されています

考察

  • AnimatedVectorDrawableのアイコンさえ用意すれば、簡単に実装可能でした
  • アニメーションアイコンの作成にはAndroid Icon Animatorを使うと良さそうです

実装方法

  • アイコンがあれば、アイコンタップ時にアイコン切り替えとアニメーションの開始を呼ぶだけでできます
private boolean menuFlag = false;
private Toolbar toolbar;
private AnimatedVectorDrawable menuDrawable;
private AnimatedVectorDrawable arrowDrawable;

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  toolbar = (Toolbar) findViewById(R.id.toolbar);
  menuDrawable = (AnimatedVectorDrawable) getDrawable(R.drawable.ic_menu_24dp);
  arrowDrawable = (AnimatedVectorDrawable) getDrawable(R.drawable.ic_arrow_24dp);

  toolbar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      if (menuFlag) {
        toolbar.setNavigationIcon(arrowDrawable);
        arrowDrawable.start();
      } else {
        toolbar.setNavigationIcon(menuDrawable);
        menuDrawable.start();
      }
      menuFlag = !menuFlag;
    }
  });
}

最後に

ちょっと長くなってしまいましたが、分かりにくいところや、ご指摘あればコメントいただけると幸いです。
今はAndroidですが、色々興味はあるので、いろんなジャンルで投稿できたらと思ってます。

11
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10