我有一个像相册这样的项目列表,我通过RecyclerView显示它。
此外,每个项目都有一个按钮,通过单击该按钮可以向服务器发送一些数据,然后滚动到列表中的下一个位置。
所以我的问题是:
如果调用了smoothScrollToPosition()方法,如何防止RecyclerView手动滚动(手势),但滚动到某个位置?
我很乐意改进@阿里提供的答案。有些假设似乎具有误导性。
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerViewForList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false"
/>
</android.support.v4.widget.NestedScrollView>
有两种选择可以做到这一点;在 XML 布局或代码中。
XML布局
android:nestedScrollingEnabled="false"
密码
recyclerViewForList.setNestedScrollingEnabled(false);
linearLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false) {
@Override
public boolean canScrollVertically() {
return false;
}
//If you want to prevent scrolling horizontally, in my case
//it was vertically
@Override
public boolean canScrollHorizontally() {
return false;
}
};
为此,您应该重写< code > recycle view 的< code>LayoutManager。滚动将被禁用,但您仍可以处理点击或任何其他触摸事件。例如:
linearLayoutManager = new LinearLayoutManager(context) {
@Override
public boolean canScrollVertically() {
return false;
}
};
recyclerView.setLayoutManager(linearLayoutManager);
如果你想调用 scrollToPosition(),可以像这样操作:
linearLayoutManager = new LinearLayoutManager(context) {
@Override
public boolean canScrollVertically() {
return true;
}
};
recyclerView.setLayoutManager(linearLayoutManager);
linearLayoutManager.scrollToPosition(youePositionInTheAdapter); // where youPositionInTheAdapter is the position you want to scroll to
然后使用第一个代码再次禁用它。
这是一个水平滚动的解决方案,它允许您关闭滚动,但仍然可以通过调用slthScrollToPotion启用它。它还允许用户与回收器视图中的子视图进行交互。
我发现其他启用临时滚动以能够调用slthScrollToPotion的解决方案的副作用是让用户中断滚动,即使在禁用触摸事件或在回收器视图顶部添加另一个视图时也是如此。
使smoothScrollToPosition工作的关键是重写LinearSmoothScroller。calculateDxToMakeVisible并删除选中以水平滚动()
class NoScrollHorizontalLayoutManager(context: Context) : LinearLayoutManager(context, RecyclerView.HORIZONTAL, false) {
override fun canScrollHorizontally(): Boolean {
return false
}
override fun smoothScrollToPosition(recyclerView: RecyclerView, state: RecyclerView.State?, position: Int) {
val linearSmoothScroller = ForceHorizontalLinearSmoothScroller(recyclerView.context)
linearSmoothScroller.targetPosition = position
startSmoothScroll(linearSmoothScroller)
}
}
class ForceHorizontalLinearSmoothScroller(context: Context) : LinearSmoothScroller(context) {
override fun calculateDxToMakeVisible(view: android.view.View, snapPreference: Int): Int {
val layoutManager = layoutManager
if (layoutManager == null) {
return 0
}
val params = view.layoutParams as RecyclerView.LayoutParams
val left = layoutManager.getDecoratedLeft(view) - params.leftMargin
val right = layoutManager.getDecoratedRight(view) + params.rightMargin
val start = layoutManager.paddingLeft
val end = layoutManager.width - layoutManager.paddingRight
return calculateDtToFit(left, right, start, end, snapPreference)
}
}
编辑:我发现用户在滚动进行时点击循环视图时仍然可以停止滚动。修复方法是覆盖RecycleView.onInterceptTouchEvent
并防止在平滑滚动正在进行或滚动状态设置为SCROLL_STATE_SETTLING
时发生事件。(使用RecycleView.addOnItemTouchListener
是行不通的,因为RecycleView停止滚动,然后侦听器在RecyleView.onInterceptTouchEvent
中返回true。)
class NoScrollRecyclerView : RecyclerView {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
override fun onInterceptTouchEvent(e : MotionEvent) : Boolean {
if (layoutManager?.isSmoothScrolling() == true || scrollState == SCROLL_STATE_SETTLING) {
return true
}
return super.onInterceptTouchEvent(e)
}
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(e :MotionEvent) : Boolean {
if (layoutManager?.isSmoothScrolling() == true || scrollState == SCROLL_STATE_SETTLING) {
return true
}
return super.onTouchEvent(e)
}
}
在其他回收器视图中有一个回收器视图。两者都需要垂直滚动。外部回收器视图滚动正常,但内部回收器视图滚动不正常。 这是代码: ViewAdapter如下: 我尝试了以下两种回收商观点,但都无法解决问题 也尝试了这个:
我有一个动态填充的RecyclerView。 当新消息到达时,我使用此代码向下滚动到最后一个条目: 现在的问题是:如果用户已经向上滚动阅读旧消息,它不应该向下滚动。怎么才能检测出来?
我已经被困在这个问题上几天了,真的需要一些帮助和理解如何用DiffUtil设置RecylerView(RV),似乎无论我尝试什么,我都无法让RV更新。我会浏览我所拥有的,希望有人能解释一下我做错了什么。 应用程序启动 创建视图模型, 然后在ViewModel中填充LiveDataList。 LayoutManager和ListAdapter应用于RV 为什么在LiveDataList中添加或删除一
我正在拼命地尝试在一个使用Kotlin的android应用上实现无休止的滚动。所有的教程要么是无用的,因为他们没有正确地解释事情。例如:https://github.com/chetdeva/recyclerView-bindings 它看起来很有前途,但作者使用了这样的短语,比如“把这个放在你的bindingadapter中”,所以我查看了这个是什么,我找到了一个java文件,但如果你在其中插入
我有一个水平回收视图。每个子级包含一个TextView和一个垂直RecyclerView。垂直RecyclerView的子级仅包含TextView。 垂直滚动非常平滑,但水平滚动滞后很多。我已经尝试在onBindViewHolder中使用swapAdapter,而不是setAdapter,但这并没有解决问题。我也尝试过更改数据集并调用notifyDataSetChanged(),但这也没有帮助。
我正在使用下面的代码创建一个回收器视图。recyclerview有一个网格布局管理器,其项计数最多为每行2个。 不幸的是,我嵌套在ConstraintLayout中的回收器视图根本没有滚动。我错过了什么?约束布局是否支持相同的?