NestedScrollView和Horizo​​ntal RecyclerView平滑滚动

我有一个垂直的nestedscrollview,其中包含一堆带有水平布局管理器设置的recyclerview。 这个想法非常类似于新的谷歌游戏商店的外观。 我能够使它起作用但它根本不光滑。 以下是问题:

1)水平回收物品项目大多数时间都无法拦截触摸事件,即使我点击它也是如此。 滚动视图似乎优先于大多数动作。 我很难在水平运动上find钩子。 这个用户体验令人沮丧,因为我需要在它工作之前尝试几次。 如果你检查游戏商店,它能够很好地拦截触摸事件,它只是运作良好。 我注意到在游戏商店中他们设置的方式是在一个垂直的回收者视图中的许多水平回收视图。 没有滚动视图。

2)水平回收视图的高度必须手动设置,并且没有简单的方法来计算子元素的高度。

这是我正在使用的布局:

    

此UI模式非常基本,很可能在许多不同的应用程序中使用。 我已经阅读了许多SO,其中ppl说将列表放在列表中是一个坏主意,但它是一个非常普遍和现代的UI模式在整个地方使用。想看netflix就像界面里面有一系列水平滚动列表垂直清单。 有没有一个顺利的方法来实现这一目标?

    来自商店的示例图片:

    Google Play商店

    Related of "NestedScrollView和Horizo​​ntal RecyclerView平滑滚动"

    所以现在修复了平滑滚动问题。 它是由设计支持库(目前为23.1.1)中的NestedScrollView中的错误引起的。

    您可以在此处阅读有关该问题和简单修复的信息: https : //code.google.com/p/android/issues/detail?id = 194398

    简而言之,在执行fling之后,nestedscrollview没有在滚动器组件上注册完成,因此需要额外的“ACTION_DOWN”事件来释放父nestedscrollview来拦截(吃掉)后续事件。 所以发生了什么事情,如果你尝试滚动你的子列表(或viewpager),在一次投掷后,第一次触摸释放父NSV绑定,随后的触摸将起作用。 这使得用户体验非常糟糕。

    基本上需要在NSV的ACTION_DOWN事件上添加这一行:

     computeScroll(); 

    这是我正在使用的:

     public class MyNestedScrollView extends NestedScrollView { private int slop; private float mInitialMotionX; private float mInitialMotionY; public MyNestedScrollView(Context context) { super(context); init(context); } private void init(Context context) { ViewConfiguration config = ViewConfiguration.get(context); slop = config.getScaledEdgeSlop(); } public MyNestedScrollView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public MyNestedScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private float xDistance, yDistance, lastX, lastY; @Override public boolean onInterceptTouchEvent(MotionEvent ev) { final float x = ev.getX(); final float y = ev.getY(); switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: xDistance = yDistance = 0f; lastX = ev.getX(); lastY = ev.getY(); // This is very important line that fixes computeScroll(); break; case MotionEvent.ACTION_MOVE: final float curX = ev.getX(); final float curY = ev.getY(); xDistance += Math.abs(curX - lastX); yDistance += Math.abs(curY - lastY); lastX = curX; lastY = curY; if (xDistance > yDistance) { return false; } } return super.onInterceptTouchEvent(ev); } 

    }

    使用此类代替xml文件中的nestedscrollview,子列表应该正确拦截和处理触摸事件。

    Phew,实际上有很多这样的错误让我想完全放弃设计支持库,并在它更成熟时重新审视它。

    我已成功使用ViewPager在垂直滚动父级中进行水平滚动:

      

    公共类UniversityKnownForPagerAdapter扩展了PagerAdapter {

     public UniversityKnownForPagerAdapter(Context context) { mContext = context; mInflater = LayoutInflater.from(mContext); } @Override public Object instantiateItem(ViewGroup container, int position) { View rootView = mInflater.inflate(R.layout.card_university_demographics, container, false); ... container.addView(rootView); return rootView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View)object); } @Override public int getCount() { return 4; } @Override public boolean isViewFromObject(View view, Object object) { return (view == object); } 

    仅发出:您必须为视图寻呼机提供固定高度