我是靠谱客的博主 安静蜗牛,最近开发中收集的这篇文章主要介绍嵌套滑动的LinearLayout(滑动隐藏头部的LinearLayout),滑动时先隐藏头部(第一个子控件)再滑动recyclerview,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

需求:LinearLayout内部包含一个头部和一个recyclerview。recyclerview可滚动,滚动时如果头部仍在可见则先滚动LinearLayout直到头部消失,再开始滚动recyclerview。

思路:
1.自定义LinearLayout实现NestedScrollingParent,getChildAt(0)获取头部,计算头部高度。将LinearLayout的高度设置为自身高度 + 头部高度(隐藏头部后仍完整显示recyclerview)。
2.在child滑动时 ,优先进行linearLayout的滑动,待linearLayout滑动到顶部或者向下滑动距离为头部高度时不再消费滑动事件并交由child继续执行。
3.为了使滑动在LinearLayout的任意区域都能滑动LinearLayout,所有child包括头部都需要实现NestedScrollingChild。或者使用NestedSrollView、Recyclerview这些已经实现NestedScrollingChild的控件。
4.仅实现滑动事件在filing时会有卡顿,为了提升用户体验应当将filing的相关方法实现。

实现:

public class HideFirstViewNestedLinearLayout extends LinearLayout implements NestedScrollingParent {
private View mHeader;
private int mHeaderHeight;
private boolean mIsNeedNestedScroll = false;
private Scroller mScroller = new Scroller(getContext());
public HideFirstViewNestedLinearLayout(Context context) {
super(context);
}
public HideFirstViewNestedLinearLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public HideFirstViewNestedLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
return true;
}
@Override
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
super.onNestedPreScroll(target, dx, dy, consumed);
//过滤横向的误操作
if (Math.abs(dx) * 1.5 > Math.abs(dy)) {
return;
}
//滑动距离不得超过头部高度
boolean headerScrollUp = dy > 0 && getScrollY() < mHeaderHeight;
//滑动距离不得小于0
boolean headerScrollDown = dy < 0 && getScrollY() > 0 && !target.canScrollVertically(-1);
if ((headerScrollUp || headerScrollDown) && isIsNeedNestedScroll()) {
if (dy + getScrollY() > mHeaderHeight) {
dy = mHeaderHeight - getScrollY();
}
if (dy + getScrollY() < 0) {
dy = 0 - getScrollY();
}
scrollBy(0, dy);
consumed[1] = dy;
}
}
@Override
public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
//当垂直方向速率大于头部高度时,开始动画自动滑动到顶部或底部
if (Math.abs(velocityY) > mHeaderHeight && isIsNeedNestedScroll()) {
if (velocityY > 0) {
mScroller.startScroll(getScrollX(), getScrollY(), 0, mHeaderHeight - getScrollY());
} else {
mScroller.startScroll(getScrollX(), getScrollY(), 0, 0 - getScrollY());
}
invalidate();
}
return super.onNestedPreFling(target, velocityX, velocityY);
}
@Override
public void computeScroll() {
super.computeScroll();
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
if (getChildCount() > 0) {
mHeader = getChildAt(0);
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
Log.d(getClass().toString(), "onSizeChanged: mHeaderHeight = " + mHeaderHeight);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mHeader.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
mHeaderHeight = 0;
if (mHeader.getLayoutParams() instanceof LinearLayout.LayoutParams) {
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) mHeader.getLayoutParams();
mHeaderHeight = mHeaderHeight + layoutParams.topMargin + layoutParams.bottomMargin;
}
mHeaderHeight = mHeaderHeight + mHeader.getMeasuredHeight();
int totalHeight;
if (mIsNeedNestedScroll) {
totalHeight = MeasureSpec.getSize(heightMeasureSpec) + mHeader.getMeasuredHeight();
} else {
totalHeight = MeasureSpec.getSize(heightMeasureSpec);
}
int mode = MeasureSpec.getMode(heightMeasureSpec);
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(totalHeight, mode));
}
public boolean isIsNeedNestedScroll() {
return mIsNeedNestedScroll;
}
public void setIsNeedNestedScroll(boolean mIsNeedNestedScroll) {
this.mIsNeedNestedScroll = mIsNeedNestedScroll;
}
}

最后

以上就是安静蜗牛为你收集整理的嵌套滑动的LinearLayout(滑动隐藏头部的LinearLayout),滑动时先隐藏头部(第一个子控件)再滑动recyclerview的全部内容,希望文章能够帮你解决嵌套滑动的LinearLayout(滑动隐藏头部的LinearLayout),滑动时先隐藏头部(第一个子控件)再滑动recyclerview所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部