仿微博个人主页时使用 CoordinatorLayout+AppBarLayout+viewpager(NestedScrollView和RecycleView)
实现方法:
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinatorlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/themBackground">
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/themBackground"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
android:id="@+id/iv_accd_companyPic"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:src="@mipmap/example_community_dymic_1"/>
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:visibility="gone"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways|snap"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
内容部分,可以是recyleView 或者 NestedScrollView 或者tableLayout+viewpager
在Activity代码中:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
直接像上面这样就可以实现类似于新浪微博的效果,网上一大堆例子。但是运行后你会发现 :当内容是RecyleView向下滑动的时AppBarLayout部分没有了惯性,当内容是
NestedScrollView 向上向下滑动时AppBarLayout都没有了惯性。(这样怎么对的起我们的设计师妹子,哈哈)
解决方案:开始在网上查了很多资料,当时看到一篇博客帮我解决了问题,这里留下这位大神的传送门 点击进入大神的博客
1.当内容是NestedScrollView时:
1.当内容是NestedScrollView时:
case MotionEvent.ACTION_UP:
if (mIsBeingDragged) {
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.addMovement(vtev);
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
int initialVelocity = (int) VelocityTrackerCompat.getYVelocity(velocityTracker,
mActivePointerId);
if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
flingWithNestedDispatch(-initialVelocity);
} else if (mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0,
getScrollRange())) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
mActivePointerId = INVALID_POINTER;
endDrag();
break;
这里我们直接复制一个NestedScrollView到自己的项目中将if(mmIsBeingDragged)注释掉
2.当内容是RecycleView时:
public final class FlingBehavior extends AppBarLayout.Behavior {
private static final int TOP_CHILD_FLING_THRESHOLD = 3;
private boolean isPositive;
public FlingBehavior() {
}
public FlingBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onNestedFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY, boolean consumed) {
if (velocityY > 0 && !isPositive || velocityY < 0 && isPositive) {
velocityY = velocityY * -1;
}
if (target instanceof RecyclerView && velocityY < 0) {
final RecyclerView recyclerView = (RecyclerView) target;
final View firstChild = recyclerView.getChildAt(0);
final int childAdapterPosition = recyclerView.getChildAdapterPosition(firstChild);
consumed = childAdapterPosition > TOP_CHILD_FLING_THRESHOLD;
}
return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed);
}
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
isPositive = dy > 0;
}
使用:将appbarlayout中的behavior替换成上面的FlingBehavior
在AppbarLayout 布局中添加
app:layout_behavior="your.package.FlingBehavior"
然后就可以流畅的使用了
最近赶项目只是找到了解决方案,还没有做深入的研究,很多原理也不是很清楚。