はじめに
PagerTabStripはタブ構造を持つUIを作るときにViewPagerとともに使用しますが、
タブ内のFragmentが持つListViewやRecyclerViewのスクロール状況に合わせてToolbar(やActionBar)をPagerTabStripもろとも出したり引っ込めたりする処理を書こうとすると、
PagerTabStripはViewPagerの子要素でなければならないという制約に引っかかってうまく実装できません。
ではどうすればよいのかというと
カスタムビューを作る
- オリジナルのPagerTabStripをコピーする(クラス名はOverlayPagerTitleStripとする)
- ソースコードを修正
OverlayPagerTitleStrip.java
public OverlayPagerTitleStrip(Context context, AttributeSet attrs) {
super(context, attrs);
/* 中略 */
/* ここから */
TypedArray types =
context.obtainStyledAttributes(attrs, R.styleable.OverlayPagerTitleStrip, 0, 0);
pagerId = types.getResourceId(R.styleable.OverlayPagerTitleStrip_parentViewPager, 0);
/* ここまで追加 */
}
@Override protected void onAttachedToWindow() {
super.onAttachedToWindow();
final ViewParent parent = getParent();
ViewPager pager = null;
if (pagerId != 0) {
View test2 = ((View) parent).findViewById(pagerId);
pager = (ViewPager) test2;
} else if (pagerId == 0 && (parent instanceof ViewPager)) {
pager = (ViewPager) parent;
} else if (pagerId == 0 && !(parent instanceof ViewPager)) {
throw new IllegalStateException(
"PagerTitleStrip is neither a direct child of a ViewPager nor did you assign the ID of the ViewPager.");
} else {
throw new IllegalStateException("PagerTitleStrip: Something went completely wrong.");
}
final PagerAdapter adapter = pager.getAdapter();
pager.setInternalPageChangeListener(mPageListener);
pager.setOnAdapterChangeListener(mPageListener);
mPager = pager;
updateAdapter(mWatchingAdapter != null ? mWatchingAdapter.get() : null, adapter);
}
- カスタムビューの属性を定義する
res/values/attr.xml
<declare-styleable name="OverlayPagerTitleStrip">
<!-- ViewPagerへの参照 -->
<attr name="parentViewPager" format="reference" />
</declare-styleable>
使うとき
activity_main.xml
<FrameLayout 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.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
<!-- ViewPagerの子にしなくてもOK -->
<yourpackage.OverlayPagerTabStrip
android:id="@+id/strip"
android:layout_width="match_parent"
android:layout_height="@dimen/tab_height"
android:layout_marginTop="?attr/actionBarSize"
app:parentViewPager="@+id/pager"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"/>
</FrameLayout>
こんな感じで
手前側 - ToolBar - PagerTabStrip - ViewPager - 奥側
になるようにFrameLayoutで重ねて、タブ内のListViewなどからToolbarと任意のView (ここではPagerTabStrip)を出したり隠したりすればOK
(このへんの処理はGoogle I/O 2014のソースコードを参考)
PagerTabStripはどうすんの?
PagerTitleStripを継承しているので、PagerTabStripのソースコードをコピーすれば多分OK
参考(ほとんどそのまま)
http://stackoverflow.com/questions/14586690/pagertabstrip-position-within-viewpager
おわりに
既に同じことできるライブラリがあったらそれ使ったほうがいいです。
(探してはみたけど見つからなかったので知ってる方がいたら教えて下さい)