RecyclerView适合大件物品

时间:2015-08-04 18:42:44

标签: android xamarin android-recyclerview

在我们的应用中,我们有一个RecyclerView,可以在水平列表中显示大项目。我们使用LinearLayoutManager来做到这一点。用户滚动屏幕时会出现此问题。当下一个大项需要出现在屏幕上时,UI被冻结。

我们想要实现的是RecyclerView项的某种延迟加载。因此,类似于facebook的实现用户看到了一个存根,一旦他停止滚动,UI就会更新以显示实际内容。

问题是 - 什么是正确的扩展点?我应该实施自定义LayoutManager吗?或者现有解决方案?

2 个答案:

答案 0 :(得分:2)

如果你使用Xamarin作为你的标签说你可以这样做:

public class  XamarinRecyclerViewOnScrollListener : RecyclerView.OnScrollListener
{
    public delegate void LoadMoreEventHandler(object sender, EventArgs e);
    public event LoadMoreEventHandler LoadMoreEvent;

    private LinearLayoutManager LayoutManager;

    public XamarinRecyclerViewOnScrollListener (LinearLayoutManager layoutManager)
    {
        LayoutManager = layoutManager;
    }

    public override void OnScrolled (RecyclerView recyclerView, int dx, int dy)
    {
        base.OnScrolled (recyclerView, dx, dy);

        var visibleItemCount = recyclerView.ChildCount;
        var totalItemCount = recyclerView.GetAdapter().ItemCount;
        var pastVisiblesItems = LayoutManager.FindFirstVisibleItemPosition();

        if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
            LoadMoreEvent (this, null);
        }
    }
}

要在您的视图中使用此功能,请使用:

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        var view = base.OnCreateView(inflater, container, savedInstanceState);

        var recyclerView = view.FindViewById<RecyclerView>(Resource.Id.my_recycler_view);
        if (recyclerView != null)
        {
            recyclerView.HasFixedSize = true;

            var layoutManager = new LinearLayoutManager(Activity);

            var onScrollListener = new XamarinRecyclerViewOnScrollListener (layoutManager);
            onScrollListener.LoadMoreEvent += (object sender, EventArgs e) => {
                //Load more stuff here
            };

            recyclerView.AddOnScrollListener (onScrollListener);

            recyclerView.SetLayoutManager(layoutManager);
        }
        return view;
    }

答案 1 :(得分:0)

如果没有看到你正在做什么,我只能提出一个高级别的建议。并且该建议是将滚动侦听器附加到recyclerView。

这对你有什么用?

        final int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();
    final int lastVisiblePosition = layoutManager.findLastVisibleItemPosition();

    myRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
        }

        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);

            switch (newState) {
                case RecyclerView.SCROLL_STATE_IDLE:
                    for (int i = firstVisiblePosition; i <= lastVisiblePosition; i++) {
                        // start content loading here
                        recyclerView.getChildAt(i).loadMyContent;
                    }
                    break;
                case RecyclerView.SCROLL_STATE_DRAGGING:
                    for (int i = firstVisiblePosition; i <= lastVisiblePosition; i++) {
                        // cancel content loading here
                        recyclerView.getChildAt(i).cancelLoad;
                    }
                    break;
                case RecyclerView.SCROLL_STATE_SETTLING:
                    // you could load content here, but it could end up off screen by the time it stops, so I would not recommend it
                    break;
            }
        }
    });

我想补充一点,如果您要加载图片,请查看Picasso library

来自Picasso的网页:

ADAPTER DOWNLOADS

自动检测适配器重用并取消先前的下载。

@Override public void getView(int position, View convertView, ViewGroup parent) {
  SquaredImageView view = (SquaredImageView) convertView;
  if (view == null) {
    view = new SquaredImageView(context);
  }
  String url = getItem(position);

  Picasso.with(context).load(url).into(view);
}