在三星GT-S7562 Android 4.0.4上获取此错误。我不是通过代码调用scrollTo方法。它正在内部调用。请帮助
java.lang.UnsupportedOperationException: RecyclerView does not support scrolling to an absolute position.
at android.support.v7.widget.RecyclerView.scrollTo(RecyclerView.java:941)
at android.view.View.setScrollX(View.java:7010)
at android.animation.PropertyValuesHolder.nCallIntMethod(Native Method)
at android.animation.PropertyValuesHolder.access$200(PropertyValuesHolder.java:35)
at android.animation.PropertyValuesHolder$IntPropertyValuesHolder.setAnimatedValue(PropertyValuesHolder.java:815)
at android.animation.ObjectAnimator.animateValue(ObjectAnimator.java:476)
at android.animation.ValueAnimator.animationFrame(ValueAnimator.java:1145)
at android.animation.ValueAnimator.setCurrentPlayTime(ValueAnimator.java:551)
at android.animation.LayoutTransition.startChangingAnimations(LayoutTransition.java:813)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1805)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2632)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4517)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
at dalvik.system.NativeStart.main(Native Method)
我也遇到了同样的问题,对我来说,这是因为我有
android:animateLayoutChanges="true"
为我的回收者视图的父视图。我去掉了它,它起作用了。
您会在一些三星、索尼、,。。。ICS的实施。我创建的两个都包括奇怪的内部视图管理。对此的一个解决方案是用您自己的类扩展RecyclerView(或生成问题的类)并使用该类。在该类中,您将基本上"吃掉"这些设备的所有可能的呈现异常。这很丑陋,很可怕,但这是我所能做的一切来解决这类问题。
对于您使用scrollTo的特定问题。。。。
package com.stackoverflow.customviews;
public class CustomRecyclerView extends RecyclerView{
private static final String TAG = "CustomRecyclerView";
public CustomRecyclerView(android.content.Context context) {
super(context);
}
public CustomRecyclerView(android.content.Context context, android.util.AttributeSet attrs) {
super(context, attrs);
}
public CustomRecyclerView(android.content.Context context, android.util.AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void scrollTo(int x, int y) {
Log.e(TAG, "CustomRecyclerView does not support scrolling to an absolute position.");
// Either don't call super here or call just for some phones, or try catch it. From default implementation we have removed the Runtime Exception trown
}
}
然后,您可以在布局xml中替换这个新类:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.stackoverflow.customviews.CustomRecyclerView
android:id="@+id/my_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:scrollbars="vertical" />
</FrameLayout>
要以编程方式进行滚动,需要使用LayoutManager。例如,LinearLayoutManager具有scrollToPositionWithOffset。GridLayoutManager扩展了LinearLayoutManager,所以您也可以使用它。代码适用于我:
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
linearLayoutManager.scrollToPositionWithOffset(0, newTopMargin - defaultMargin);
}
由于回收器父级中的以下原因,我遇到了同样的警告问题:
android:animateLayoutChanges="true"
如果你想保留动画,只需将回收器像framelayout
一样放在另一个父级中即可。它对我来说效果很好,动画也很好。
正如其他人在回答中所说,RecyclerView
的父布局中的android:animateLayoutChanges="true"
导致了这个问题,但解决方案比其他人所说的更容易。
只需要将RecyclerView
放入一个没有android:animateLayoutChanges
属性的新Layout
中。
例如:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true">
...
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
只有当RecyclerView位于具有XML属性的直接父视图内时,才会出现警告
android:animateLayoutChanges="true"
就像@Aalap和@luis所说的(@luis甚至给出了一个想法,如何让这个XML属性具有几乎相同的布局层次结构)。
我想发布一个有点不同的选项。如果你有这种情况,你可能想在父布局中设置一些视图更改的动画,但不想在RecyclerView中设置,否则这个会有点错误。如果您需要RecyclerView动画,最好在RecyclerView适配器而不是XML中执行此操作。
所以最后,如果你需要动画,当某些东西在RecyclerView之外发生变化时,最好放
android:animateLayoutChanges="true"
不是进入RecyclerView的父视图,而是进入要设置动画的视图的父视图。
简称:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/top_parent_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:id="@+id/header_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:clickable="true"
android:animateLayoutChanges="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:id="@+id/header_arrow_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="end|center_vertical"/>
</FrameLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
这意味着:避免用带有android:animateLayoutChanges="true"的父视图包装RecyclerView