RecyclerView 数据集更改时奇怪的滚动

RecyclerView Strange scrolling when dataset changed

我正在使用 recyclerView (TwowayView),它在数据更改时表现异常(滚动)。我正在使用以下代码为其设置适配器(每次数据更改时)。

// sites = list , rvlinks = twowayview

    adapter = new SitesAdapter(getActivity(), rvLinks, LinksFragment.this, sites);
    rvLinks.setAdapter(adapter);

为了更好的理解,我制作了错误视频。

https://youtu.be/xPvHper3gpc

如图所示,尽管列表中只有 2 个项目,但 recyclerview 的顶部和底部区域很大(见图)。

仅使用 notifyDatasetChanged() 产生相同的结果。卡在这。

Recyclerview 设置了固定大小。

rvLinks.setHasFixedSize(true);

任何帮助都会很棒。

这是我的 xml 布局:

 <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/dummyview"
    android:layout_below="@+id/sp_category"
    android:layout_marginTop="15dp"
    android:background="@drawable/white_round">

    <Widget.EmptyRecyclerView
    android:id="@+id/rv_links"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    android:drawSelectorOnTop="false"

    android:orientation="vertical"
    app:twowayview_layoutManager="GridLayoutManager"
    app:twowayview_numColumns="2"

    tools:context=".MainActivity" />



    <TextView
        android:id="@+id/tv_empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="No Sites Found" />

</RelativeLayout>

这是我的 RecyclerView 实现了 emptyView。

public class EmptyRecyclerView extends TwoWayView {
    private View emptyView;
    final private AdapterDataObserver observer = new AdapterDataObserver() {
        @Override
        public void onChanged() {
            checkIfEmpty();
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            checkIfEmpty();
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            checkIfEmpty();
        }
    };

    public EmptyRecyclerView(Context context) {
        super(context);
    }

    public EmptyRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EmptyRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    void checkIfEmpty() {
        if (emptyView != null && getAdapter() != null) {
            final boolean emptyViewVisible = getAdapter().getItemCount() == 0;
            emptyView.setVisibility(emptyViewVisible ? VISIBLE : GONE);
            setVisibility(emptyViewVisible ? GONE : VISIBLE);
        }
    }

    @Override
    public void setAdapter(Adapter adapter) {
        final Adapter oldAdapter = getAdapter();
        if (oldAdapter != null) {
            oldAdapter.unregisterAdapterDataObserver(observer);
        }
        super.setAdapter(adapter);
        if (adapter != null) {
            adapter.registerAdapterDataObserver(observer);
        }

        checkIfEmpty();
    }

    public void setEmptyView(View emptyView) {
        this.emptyView = emptyView;
        checkIfEmpty();
    }
}

尝试为你的 recyclerview 设置一个准确的高度,因为它不符合 wrap_content 并且设置 match_parent 将占据整个 space 低于你的列表视图

的高度

开始看到结果后,您可以为您的回收视图使用自定义布局管理器,覆盖 onMeasure()。

查看此示例

Nested Recycler view height doesn't wrap its content

按照@random 的建议,我尝试了 match_parent,但 TwoWayView 也有同样的问题。所以我决定在 support-v7 lib.

中将其更改为 RecyclerView

令人惊讶的是它按预期工作。可能是它自己 GridLayoutManager 做了一些奇特的工作导致了问题。 GridlayoutManager 的 recyclerview 效果很好。

感谢您的帮助。 :)