遇到一个问题 ,请大佬们帮看看,能解决或者提供解决思路的兄弟得来杯 Manner。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
waitMeOY
V2EX    Android

遇到一个问题 ,请大佬们帮看看,能解决或者提供解决思路的兄弟得来杯 Manner。

  •  
  •   waitMeOY 9 天前 1621 次点击
    先祝大家假期快乐,但是我被一个问题困扰不已。
    问题:类似传承电商首页实现 tab 吸顶的效果,nestscrollview+viewpager+recyclerview

    我在外层的 Nestscrollview 自定义的时候当滚动一定距离后我把 fling 传递给内层的 reyclerview 去 fling,然后会有一瞬间的加速感,不同设备体现还不一样,滚动的代码大概就这么多。

    请问大家有什么思路。
    之前有朋友提出“NestedScrollingParnt3Layout 这个是自定义的吧 换普通 recyclerview 然后 item 放 recyclerview 。有能复用的 item 尽量用 recyclerview 看着像资源太多卡顿了”
    但是我觉得我自定义的实际是继承了 nestscrollview ,继承系统的 然后重写了一些嵌套滚动的方法,这么设计是没毛病的。
    11 条回复    2025-10-01 12:20:16 +08:00
    waitMeOY
        1
    waitMeOY  
    OP
       9 天前
    代码传不上去,贴就提示 不受欢迎 ,访问被拒绝。现在有什么贴图的办法吗
    prettybot
        2
    prettybot  
       9 天前
    放 gist 片段链接呗
    waitMeOY
        3
    waitMeOY  
    OP
       9 天前
    private void initView(Context context) {
    mFlingHelper = new FlingHelper2(context);
    mScroller = new OverScroller(context);
    mMaximumFlingVelocity = ViewConfiguration.get(context).getScaledMaximumFlingVelocity();
    velocityDecayCalculator = new VelocityDecayCalculator(context);
    Log.d(TAG, "速度限定为: " + mMaximumFlingVelocity);
    setOnScrollChangeListener(new OnScrollChangeListener() {
    @Override
    public void onScrollChange(@NonNull NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
    Log.d("onScrollChange", "---------isFlinging-------" + velocityY + "");
    if (isStartFling) {
    totalDy = 0;
    isStartFling = false;
    }

    if (scrollY == getTopViewHeight() && !mChildrenScrollWrapperView.isScrollToBottom()) {
    //开始底部的滑动
    // dispatchChildFlingImproved();
    float v1 = NestedNSVOverScroller.invokeCurrentVelocity(NestedScrollingParent3Layout.this);
    dispatchChildFling(v1);
    }
    totalDy += scrollY - oldScrollY;
    }
    });
    }
    waitMeOY
        4
    waitMeOY  
    OP
       9 天前
    private void dispatchChildFling(float v1) {
    startChildScrollWithScroller( v1);
    // if (velocityY != 0) {
    // double totalDistance = mFlingHelper.getSplineFlingDistance(velocityY);
    // //根据速度求的距离大于滑动的距离时
    // if (totalDistance > totalDy) {
    // //求距离差的速度
    // if (totalDistance > 0 && mChildrenScrollWrapperView != null) {
    // // 开始子视图滚动
    //
    // } else {
    // Log.d(TAG, "子视图无法滚动或剩余距离不足");
    // }
    // }
    // }
    }

    /**
    * 使用 Scroller 开始子视图滚动
    */
    private void startChildScrollWithScroller( float velocity) {
    if (mChildrenScrollWrapperView == null || mChildrenScrollWrapperView.isScrollToBottom()) {
    Log.d(TAG, "子视图无法滚动");
    return;
    }
    // 停止父视图的滚动
    fling(0);
    Log.d(TAG, "startChildScrollWithScroller=====" + velocity);
    // 重置滚动状态
    mLastScrollY = 0;
    mChildrenScrollWrapperView.flingY((int) velocity);
    }
    waitMeOY
        5
    waitMeOY  
    OP
       9 天前
    <com.example.myapplication.ui.activity.viewpager.nestedsliding.NestedScrollingParent3Layout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <!-- ........省略头部内容-->
    </FrameLayout>


    <com.example.myapplication.ui.activity.viewpager.nestedsliding.WrapContentViewPager2
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
    </LinearLayout>

    </com.example.myapplication.ui.activity.viewpager.nestedsliding.NestedScrollingParent3Layout>
    waitMeOY
        6
    waitMeOY  
    OP
       9 天前
    @prettybot 放了
    cz5424
        7
    cz5424  
       9 天前
    Android 官方推荐的嵌套滑动链路:

    外层做 AppBarLayout + CoordinatorLayout ,或者 ViewPager2 里每个 tab 用 RecyclerView ,本身就支持嵌套 fling ,不需要自己拦截再转发。

    如果能换掉自定义的 NestedScrollingParent3Layout ,很多坑就不必自己处理。
    cz5424
        8
    cz5424  
       9 天前
    你这个“瞬间加速感”其实是 fling 惯性传递两边叠加了,NestedScrollView 停止时剩余的速度没有被完全吸收,又被你手动算出来传给子 RecyclerView 去 fling ,一旦计算或时机没控制好,就会造成那一下猛冲的体验。
    OneLiteCore
        9
    OneLiteCore  
       9 天前
    个人的建议是别把 Tab 吸顶的逻辑嵌套到 NestScrollView 里面去,而是独立成一个单独的 View 。界面的结构是:

    FrameLayout:
    -> ViewPager
    -> 顶部 padding 且 clipPadding=flase 的 RecyclerView 的 Fragment
    -> 置顶 TabBar

    此时 TabBar 是悬浮在整个界面上的,然后由于 RecyclerView 带有顶部 padding 所以不会有内容被遮挡,而 clipPadding=flase 会使得这部分 padding 会像 item 希望被滚动。

    之后只要监听所有 RecyclerView 的活动事件,dy 增减则同步改动 TabBar 的 y 到屏幕外面就行了。想要动画的话或者更复杂的控制直接加状态机。

    此时界面只有接口有关联,就不存在嵌套滚动这种复杂的实现。
    OneLiteCore
        10
    OneLiteCore  
       9 天前
    之后可以把“监听 RecyclerView 滚动动态改变 bar 高度”的这个逻辑封装起来成工具,然后底部或者顶部的 bar 吸顶或者隐藏都可以直接复用。
    OneLiteCore
        11
    OneLiteCore  
       9 天前
    甚至可以进一步简化成“根据 dy 变化一个 view 的 y 属性”,只要接口抽象够解耦就行。然后就可以直接复用到 ListView 或者 ScrollView 等有 dy 监听的控件上。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5695 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 06:23 PVG 14:23 LAX 23:23 JFK 02:23
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86