我希望获得Google+个人资料页面效果(请查看随附的GIF)
到目前为止,我已经实现了:滚动到底部(向上拖动)时,标题图像将缩小,SlidingTab
将固定在ActionBar
下方。就像GIF的前半部分一样
但是我无法做到相反:当RecyclerView
到达第一个孩子时,它会停止发送onScrolled
事件,并且标题视图无法展开。
继承我的布局文件:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:animateLayoutChanges="true"
android:fitsSystemWindows="false"
tools:context=".ProfileActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/profile_header_background_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/header"
android:layout_alignParentTop="true"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
tools:src="@drawable/ic_launcher" />
<LinearLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:orientation="vertical">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar_actionbar_layout" />
<include
android:id="@+id/profile_bio_view"
layout="@layout/profile_header" />
</LinearLayout>
<SlidingTabLayout
android:id="@+id/profile_sliding_tags"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/header" />
<android.support.v4.view.ViewPager
android:id="@+id/profile_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_below="@+id/profile_sliding_tags" />
</RelativeLayout>
<include layout="@layout/drawer_navigation_layout" />
</android.support.v4.widget.DrawerLayout>
在ViewPager
&#39; RecyclerView
内,我做了这个:
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
Bus.post(new ProfileScrolledEvent(recyclerView.getChildAt(0).getTop(), state, dy));
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
state = newState;
// intercept the touch event if scroll state=0 (IDLE)
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
Bus.post(new ProfileScrolledEvent(recyclerView.getChildAt(0).getTop(), state, 0));
recyclerView.getParent().getParent().requestDisallowInterceptTouchEvent(true);
} else {
recyclerView.getParent().getParent().requestDisallowInterceptTouchEvent(false);
}
}
});
因此,当RecyclerView
滚动时,我可以将滚动的像素发布到活动中,并在我的活动中:
@Subscribe
public void onProfileScrolledEvent(ProfileScrolledEvent event) {
// FIXME: can scroll with shrink header, but the header will not expand as expected
int scrollState = event.getScrollState();
int pixels = event.getScrolledPixels();
int recyclerViewTop = event.getRecyclerViewTop();
if (pixels == 0 && scrollState == 0) {
//TODO intercept the touch event
shouldIntercept = true;
} else {
shouldIntercept = false;
scrollProfile(recyclerViewTop);
}
LogUtil.debug("Bus event. top: " + recyclerViewTop + " state: " + scrollState + " pixels: " + pixels);
}
private void scrollProfile(int pixels) {
ViewGroup.LayoutParams headerParams = profileBioView.getLayoutParams();
headerParams.height = profileBioView.getHeight() + pixels / 2;
currentHeaderHeight = headerParams.height;
LogUtil.debug("currentHeaderHeight: " + currentHeaderHeight +
"\n profileBioView.getHeight: " + profileBioView.getHeight() +
"\n background.getHeight: " + headerBackground.getHeight());
ViewGroup.LayoutParams imageParams = headerBackground.getLayoutParams();
imageParams.height = headerParams.height;
if (headerParams.height <= 0) {
headerBackground.setVisibility(View.INVISIBLE);
} else {
headerBackground.setVisibility(View.VISIBLE);
slidingTabLayout.setTranslationY(pixels / 2);
if (headerParams.height > origHeaderHeight) {
headerParams.height = origHeaderHeight;
imageParams.height = origHeaderHeight;
}
profileBioView.setLayoutParams(headerParams);
headerBackground.setLayoutParams(imageParams);
}
}
问题是,当RecyclerView到达其第一个孩子时,onScrolled
事件停止,ScrollState
变为IDLE
。此时,我想通知父活动拦截TouchEvent
并继续移动标题视图。但是,当我尝试在活动中注册GestureListener
时,它根本就没有被调用。
那么还有更好的方法吗?或者是否可以在特定条件下拦截孩子TouchEvent
?
仅供参考:我使用Otto Bus发布消息,请点击此处:http://square.github.io/otto/