読者です 読者をやめる 読者になる 読者になる

ほげほげ(仮)

仮死状態

Androidでスクロールした時にToolbarを隠す

Android

概要

Google Playのようにスクロールした時にToolbar部分を隠す単純な方法です。

SupportLibraryのみを使って実装できます。

余計な実装は極力省いていますのでActivityのみで実装してます。

注意

先に注意事項を。

これをLollipop未満のバージョンで実現するにはスクロールするコンテンツ部分に制限があります。

RecyclerViewまたはNestedScrollViewが必要になります。例えば普通のListViewではLollipop未満では実現できませんので注意です。(Lollipop以降でListViewでの実装は後述します)

実行イメージ

実装手順

gradle

build.gradleは次のようになります。

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.0.1'
    compile 'com.android.support:design:23.0.1'
    compile 'com.android.support:recyclerview-v7:23.0.1'
}

スタイル

style.xmlの設定です。

Toolbarを使うのでNoActionBarを指定してます。他の色とかは適当です。

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">#1EBCD2</item>
        <item name="android:textColorPrimary">#FFFFFF</item>
        <item name="android:textColorSecondary">#B4EBF1</item>
    </style>
</resources>

レイアウト

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tab_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            app:tabIndicatorColor="#FFFF8D" />
    </android.support.design.widget.AppBarLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</android.support.design.widget.CoordinatorLayout>

CoordinatorLayoutAppBarLayoutが重要になります。ほぼこれだけで実現できます。

あと今回はサンプルなのでTabLayoutはただ表示してるだけで特に機能は無いです。(本来であればViewPager等を設定すると思います。)

RecyclerView

Adapterとレイアウトファイルが必要なのでサンプルとして載せときます。

Adapterは特別ややこしいことはせずTextViewに表示するだけです。

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {

    private List<String> data;

    private LayoutInflater inflater;

    public RecyclerAdapter(Context context, List<String> data) {
        this.data = data;
        inflater = LayoutInflater.from(context);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        return new ViewHolder(inflater.inflate(R.layout.list_item, viewGroup, false));
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        viewHolder.textView.setText(data.get(i));
    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        final TextView textView;
        public ViewHolder(View view) {
            super(view);
            textView = (TextView) view.findViewById(R.id.text);
        }
    }
}

レイアウトファイルです。

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

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

Activity

public class MainActivity extends AppCompatActivity {

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

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        tabLayout.addTab(tabLayout.newTab().setText("Tab1"));
        tabLayout.addTab(tabLayout.newTab().setText("Tab2"));

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        recyclerView.setAdapter(new RecyclerAdapter(this, createData()));

    }

    private List<String> createData() {
        List<String> data = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            data.add(String.valueOf(i));
        }
        return data;
    }
}

Activity側の実装としては実は特別なことはしてません。

完成

ここまで完成です。

重要なのはCoordinatorLayoutAppBarLayoutです。

補足

TabLayoutも隠したい。

スクロールしたときに隠すかはapp:layout_scrollFlagsによって制御されますので、TabLayoutにも属性を追加してあげるとスクロールしたときに隠れます。

<android.support.design.widget.TabLayout
    android:id="@+id/tab_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    app:layout_scrollFlags="scroll|enterAlways"
    app:tabIndicatorColor="#FFFF8D" />

設定値についてはここを参照してください。

ListViewで使いたい

Lollipop以降っていう条件でいいからListViewで使いたい場合は次のようにすると可能です。

ListView listView = (ListView) findViewById(R.id.list_view);
ViewCompat.setNestedScrollingEnabled(listView, true);

参考