我无法禁用滚动RecyclerView.我试着打电话rv.setEnabled(false)但我仍然可以滚动.
如何禁用滚动?
我正在使用RecyclerView,ScrollListener:
mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener()
{
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState)
{
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
{
super.onScrolled(recyclerView, dx, dy);
// Do my logic
}
});
Run Code Online (Sandbox Code Playgroud)
当我用手指滚动时,滚动侦听器触发了罚款.
但是当我逐步滚动时,就像那样:
mRecyclerView.scrollToPosition(LAST_POSITION);
Run Code Online (Sandbox Code Playgroud)
滚动侦听器未被触发.
This question was asked before in a too broad and unclear way here, so I've made it much more specific, with full explanation and code of what I've tried.
I'm required to mimic the way the Google Calendar has a view at the top, that can animate and push down the view at the bottom, yet it has extra, different behavior. I've summarized what I'm trying to do on 3 characteristics:
android android-collapsingtoolbarlayout android-appbarlayout
如果您的RecyclerView获取新项目,最好使用notifyItemRangeInserted每个项目的唯一,稳定的ID,以便它可以很好地动画,而不会更改您看到的太多:
正如您所看到的,项目"0"(列表中的第一个)在我之前添加更多项目时保持在同一位置,就像没有任何更改一样.
这是一个很好的解决方案,当你在其他任何地方插入项目时,它也适合其他情况.
但是,它并不适合所有情况.有时,我从外面得到的是:"这里有一个新的项目清单,有些是新的,有些是相同的,有些是更新/删除的".
因此,我不能再使用notifyItemRangeInserted,因为我不知道添加了多少.
问题是,如果我使用notifyDataSetChanged,滚动会更改,因为当前项目之前的项目数量已更改.
这意味着您当前查看的项目将被视觉移到一边:
正如您现在所看到的,当我在第一个项目之前添加更多项目时,它们会将其推下来.
我希望当前可查看的项目尽可能多地保留,优先级最高的一个(在这种情况下为"0").
对于用户,他不会注意到当前项目之外的任何内容,除了一些可能的最终案例(删除当前项目以及之后的项目或以某种方式更新当前项目).它看起来好像我用过notifyItemRangeInserted.
我试图挽救当前的滚动状态或位置,后来恢复它,如这里,但没有解决方案存在的有固定这一点.
这是我尝试过的POC项目:
class MainActivity : AppCompatActivity() {
val listItems = ArrayList<ListItemData>()
var idGenerator = 0L
var dataGenerator = 0
class ListItemData(val data: Int, val id: Long)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val adapter = object : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
val inflater = LayoutInflater.from(this@MainActivity)
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder {
return object : RecyclerView.ViewHolder(inflater.inflate(android.R.layout.simple_list_item_1, parent, …Run Code Online (Sandbox Code Playgroud) 可以使用以下方法获取当前的语言环境方向:
val isRtl=TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL
Run Code Online (Sandbox Code Playgroud)
如果开发人员设置了它,也可以获得视图的布局方向:
val layoutDirection = ViewCompat.getLayoutDirection(someView)
Run Code Online (Sandbox Code Playgroud)
视图的默认layoutDirection不基于其语言环境.它实际上是LAYOUT_DIRECTION_LTR.
当您将设备的语言环境从LTR(从左到右)语言环境(如英语)更改为RTL(从右到左)语言环境(如阿拉伯语或希伯来语)时,视图将相应地对齐,但值为默认获取视图将保留LTR ...
这意味着在给定视图的情况下,我看不出如何确定它将采用的正确方向.
我做了一个简单的POC.它有一个带有TextView的LinearLayout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/linearLayout" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:gravity="center_vertical" tools:context=".MainActivity">
<TextView
android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Hello World!"/>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
在代码中,我编写了语言环境和视图的方向:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val isRtl = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL
Log.d("AppLog", "locale direction:isRTL? $isRtl")
Log.d("AppLog", "linearLayout direction:${layoutDirectionValueToStr(ViewCompat.getLayoutDirection(linearLayout))}")
Log.d("AppLog", "textView direction:${layoutDirectionValueToStr(ViewCompat.getLayoutDirection(textView))}")
}
fun layoutDirectionValueToStr(layoutDirection: Int): String =
when (layoutDirection) {
ViewCompat.LAYOUT_DIRECTION_INHERIT -> …Run Code Online (Sandbox Code Playgroud)