首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RecyclerView和SwipeRefreshLayout

RecyclerView和SwipeRefreshLayout
EN

Stack Overflow用户
提问于 2014-08-07 09:01:56
回答 13查看 88.7K关注 0票数 64

我正在使用新的RecyclerView-Layout在一个SwipeRefreshLayout,并经历了一个奇怪的行为。当将列表滚动回顶部时,有时顶部的视图会被剪掉。

如果我试图滚动到顶部,现在-拉到-刷新触发器。

如果我尝试移除回收器周围的刷-刷新-布局,问题就消失了。而且它可以在任何手机上复制(不仅仅是L-预览设备)。

代码语言:javascript
复制
 <android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/contentView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="gone">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/hot_fragment_recycler"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.v4.widget.SwipeRefreshLayout>

这就是我的布局--行是由RecyclerViewAdapter动态构建的(这个列表中有两个视图类型)。

代码语言:javascript
复制
public class HotRecyclerAdapter extends TikDaggerRecyclerAdapter<GameRow> {

private static final int VIEWTYPE_GAME_TITLE = 0;
private static final int VIEWTYPE_GAME_TEAM = 1;

@Inject
Picasso picasso;

public HotRecyclerAdapter(Injector injector) {
    super(injector);
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position, int viewType) {
    switch (viewType) {
        case VIEWTYPE_GAME_TITLE: {
            TitleGameRowViewHolder holder = (TitleGameRowViewHolder) viewHolder;
            holder.bindGameRow(picasso, getItem(position));
            break;
        }
        case VIEWTYPE_GAME_TEAM: {
            TeamGameRowViewHolder holder = (TeamGameRowViewHolder) viewHolder;
            holder.bindGameRow(picasso, getItem(position));
            break;
        }
    }
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    switch (viewType) {
        case VIEWTYPE_GAME_TITLE: {
            View view = inflater.inflate(R.layout.game_row_title, viewGroup, false);
            return new TitleGameRowViewHolder(view);
        }
        case VIEWTYPE_GAME_TEAM: {
            View view = inflater.inflate(R.layout.game_row_team, viewGroup, false);
            return new TeamGameRowViewHolder(view);
        }
    }
    return null;
}

@Override
public int getItemViewType(int position) {
    GameRow row = getItem(position);
    if (row.isTeamGameRow()) {
        return VIEWTYPE_GAME_TEAM;
    }
    return VIEWTYPE_GAME_TITLE;
}

这是适配器。

代码语言:javascript
复制
   hotAdapter = new HotRecyclerAdapter(this);

    recyclerView.setHasFixedSize(false);
    recyclerView.setAdapter(hotAdapter);
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    contentView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            loadData();
        }
    });

    TypedArray colorSheme = getResources().obtainTypedArray(R.array.main_refresh_sheme);
    contentView.setColorSchemeResources(colorSheme.getResourceId(0, -1), colorSheme.getResourceId(1, -1), colorSheme.getResourceId(2, -1), colorSheme.getResourceId(3, -1));

以及包含FragmentSwipeRefreshLayout的代码。

如果其他人经历过这种行为并解决了它,或者至少找到了原因?

EN

回答 13

Stack Overflow用户

发布于 2014-08-07 13:21:24

addOnScrollListener of RecyclerView中编写以下代码

如下所示:

代码语言:javascript
复制
    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            int topRowVerticalPosition =
                    (recyclerView == null || recyclerView.getChildCount() == 0) ? 0 : recyclerView.getChildAt(0).getTop();
            swipeRefreshLayout.setEnabled(topRowVerticalPosition >= 0);

        }

        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
        }
    });
票数 75
EN

Stack Overflow用户

发布于 2014-10-02 11:53:01

我最近遇到了同样的问题。我尝试了@Krunal_Patel建议的方法,但在我的Nexus 4中,它大部分时间都起作用,而在三星星系s2中却根本不起作用。在调试时,recyclerView.getChildAt(0).getTop()对RecyclerView总是不正确。因此,在研究了各种方法之后,我想我们可以使用LayoutManager的方法LayoutManager()来预测RecyclerView的第一项是否可见,从而启用下面的SwipeRefreshLayout.Find代码。希望它能帮助那些试图解决同样问题的人。干杯。

代码语言:javascript
复制
    recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {

        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        }

        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            swipeRefresh.setEnabled(linearLayoutManager.findFirstCompletelyVisibleItemPosition() == 0);
        }
    });
票数 13
EN

Stack Overflow用户

发布于 2015-04-07 06:46:06

在我的情况下,这就是我解决这个问题的方法。对于其他人来说,这可能是有用的,他们最终会在这里寻找类似于此的解决方案。

代码语言:javascript
复制
recyclerView.addOnScrollListener(new OnScrollListener()
    {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy)
        {
            // TODO Auto-generated method stub
            super.onScrolled(recyclerView, dx, dy);
        }

        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState)
        {
            // TODO Auto-generated method stub
            //super.onScrollStateChanged(recyclerView, newState);
            int firstPos=linearLayoutManager.findFirstCompletelyVisibleItemPosition();
            if (firstPos>0)
            {
                swipeLayout.setEnabled(false);
            }
            else {
                swipeLayout.setEnabled(true);
            }
        }
    });

我希望这对正在寻找类似解决方案的人有一定的帮助。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25178329

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档