Code Monkey home page Code Monkey logo

xrecyclerview's Introduction

XRecyclerView

a RecyclerView that implements pullrefresh , loadingmore and header featrues.you can use it like a standard RecyclerView. you don't need to implement a special adapter .qq 群478803619 Screenshots

demo

on real device it is much more smoother. Usage

gradle

// 1.6.0 is the main
compile 'com.jcodecraeer:xrecyclerview:1.6.0'

just like a standard RecyclerView

LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mAdapter);

pull to refresh and load more

the pull to refresh and load more featrue is enabled by default. we provide a callback to trigger the refresh and LoadMore event.

 mRecyclerView.setLoadingListener(new XRecyclerView.LoadingListener() {
    @Override
    public void onRefresh() {
       //refresh data here
    }

    @Override
    public void onLoadMore() {
       // load more data here
    }
});

new function of 1.5.7 version.

mRecyclerView
    .getDefaultRefreshHeaderView() // get default refresh header view
    .setRefreshTimeVisible(true);  // make refresh time visible,false means hiding

// if you are not sure that you are 100% going to
// have no data load back from server anymore,do not use this
@Deprecated
public void setEmptyView(View emptyView) {
    ...
}

new function of 1.5.6 version,fixed a memory leak problem,use the code below to release XR's memory

// any time,when you finish your activity or fragment,call this below
if(mRecyclerView != null){
    mRecyclerView.destroy(); // this will totally release XR's memory
    mRecyclerView = null;
}

new function of 1.5.3 version,you can use XR in the sticky scroll model now,like the code below,the demo activity is 'LinearStickyScrollActivity'

final View topView = findViewById(R.id.topView);
final View tabView = findViewById(R.id.tabView);
final View content = findViewById(R.id.contentView);

final StickyScrollLinearLayout s = findViewById(R.id.StickyScrollLinearLayout);
s.addOnLayoutChangeListener(
        new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                if(s.getContentView() != null)
                    return;
                // 放在这里是为了等初始化结束后再添加,防止 height 获取 =0
                // add from here just in case they height==0
                s.setInitInterface(
                        new StickyScrollLinearLayout.StickyScrollInitInterface() {
                            @Override
                            public View setTopView() {
                                return topView;
                            }

                            @Override
                            public View setTabView() {
                                return tabView;
                            }

                            @Override
                            public View setContentView() {
                                return content;
                            }
                        }
                );
            }
        }
);

call notifyItemRemoved or notifyItemInserted, remember to use the functions inside XRecyclerView

listData.remove(pos);
mRecyclerView.notifyItemRemoved(listData,pos);

and of course you have to tell our RecyclerView when the refreshing or loading more work is done. you can use

mRecyclerView.loadMoreComplete();

to control when the item number of the screen is list.size-2,we call the onLoadMore

mRecyclerView.setLimitNumberToCallLoadMore(2); // default is 1

to notify that the loading more work is done. and

 mRecyclerView.refreshComplete();

to notify that the refreshing work is done.

here is what we get:

default

call refresh() manually(I change the previous setRefreshing() method to refresh() )

mRecyclerView.refresh();

custom refresh and loading more style

pull refresh and loading more style is highly customizable.

custom loading style

the loading effect we use the AVLoadingIndicatorView . and it is built in(make a little change). we provide all the effect in AVLoadingIndicatorView library besides we add a system style. you can call

mRecyclerView.setRefreshProgressStyle(int style);

and

mRecyclerView.setLaodingMoreProgressStyle(int style);

to set the RefreshProgressStyle and LaodingMoreProgressStyle respectively.

for example

mRecyclerView.setRefreshProgressStyle(ProgressStyle.BallSpinFadeLoader);

refreshloadingballspinfade

mRecyclerView.setLaodingMoreProgressStyle(ProgressStyle.SquareSpin);

loadingmoresquarespin

BallPulse effect

BallPulse

all the effect can be get in the ProgressStyle class

public class ProgressStyle {
    public static final int SysProgress=-1;
    public static final int BallPulse=0;
    public static final int BallGridPulse=1;
    public static final int BallClipRotate=2;
    public static final int BallClipRotatePulse=3;
    public static final int SquareSpin=4;
    public static final int BallClipRotateMultiple=5;
    public static final int BallPulseRise=6;
    public static final int BallRotate=7;
    public static final int CubeTransition=8;
    public static final int BallZigZag=9;
    public static final int BallZigZagDeflect=10;
    public static final int BallTrianglePath=11;
    public static final int BallScale=12;
    public static final int LineScale=13;
    public static final int LineScaleParty=14;
    public static final int BallScaleMultiple=15;
    public static final int BallPulseSync=16;
    public static final int BallBeat=17;
    public static final int LineScalePulseOut=18;
    public static final int LineScalePulseOutRapid=19;
    public static final int BallScaleRipple=20;
    public static final int BallScaleRippleMultiple=21;
    public static final int BallSpinFadeLoader=22;
    public static final int LineSpinFadeLoader=23;
    public static final int TriangleSkewSpin=24;
    public static final int Pacman=25;
    public static final int BallGridBeat=26;
    public static final int SemiCircleSpin=27;
}

refresh arrow icon

we provide a default arrow icon:

ic_pulltorefresh_arrow

but if you don't like it,you can replace it with any other icon you want. just call

mRecyclerView.setArrowImageView(R.drawable.iconfont_downgrey);

customarrow

disable refresh and load more featrue

if you don't want the refresh and load more featrue(in that case,you probably dont'n need the lib neither),you can call

mRecyclerView.setPullRefreshEnabled(false);

and

mRecyclerView.setPullRefreshEnabled(true);

in which false means disabled ,true means enabled. ##Header you can add header to XRecyclerView,just call addHeaderView().

View header =   LayoutInflater.from(this).inflate(R.layout.recyclerview_header, (ViewGroup)findViewById(android.R.id.content),false);
mRecyclerView.addHeaderView(header);

if you like ,you can add two header

View header =   LayoutInflater.from(this).inflate(R.layout.recyclerview_header, (ViewGroup)findViewById(android.R.id.content),false);
View header1 =   LayoutInflater.from(this).inflate(R.layout.recyclerview_header1, (ViewGroup)findViewById(android.R.id.content),false);
mRecyclerView.addHeaderView(header);
mRecyclerView.addHeaderView(header1);

License

Copyright 2015 jianghejie

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

xrecyclerview's People

Contributors

af913337456 avatar daaao avatar damonzh avatar davideas avatar jianghejie avatar mahuafactory avatar nefeed avatar whmbuaa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xrecyclerview's Issues

顶部刷新完成弹回之后,状态重置有缺陷

下拉刷新完成之后,会有个刷新完成的提示字样,然后会将header还原,问题就是,这个延迟还原,会让header的起始状态 中的 下拉刷新提示字样 也会显示一下,个人认为这个体验非常不好,参照qq消息列表,下拉刷新完成之后 也有提示刷新完成字样,但是header回弹的时候 没有显示下拉提示

加载更多触发条件

希望改为数据必须多于一屏在进行加载,不足一屏的时候屏蔽加载更多

app name

你的库里面String 有一个app name 字符串,把我本地的给替换掉了。导致我运行起来,app 名字都变成了XRecyclerView

关于加载更多的时候需执行两次才会隐藏底部

  1. mHasMore 默认为false,主要判断是否更多数据:

public void loadMoreFinish(boolean hasMore){
this.mHasMore = hasMore;
}

  1. 修改loadMoreComplete方法:

    public void loadMoreComplete() {
    isLoadingData = false;
    View footView = mFootViews.get(0);
    if (footView instanceof LoadingMoreFooter) {
    ((LoadingMoreFooter) footView).setState(mHasMore ? LoadingMoreFooter.STATE_COMPLETE : LoadingMoreFooter.STATE_NOMORE);
    } else {
    footView.setVisibility(View.GONE);
    }
    isnomore = true;
    /* if (previousTotal < getLayoutManager().getItemCount()) {
    if (footView instanceof LoadingMoreFooter) {
    ((LoadingMoreFooter) footView).setState(LoadingMoreFooter.STATE_COMPLETE);
    } else {
    footView.setVisibility(View.GONE);
    }
    } else {
    if (footView instanceof LoadingMoreFooter) {
    ((LoadingMoreFooter) footView).setState(LoadingMoreFooter.STATE_NOMORE);
    } else {
    footView.setVisibility(View.GONE);
    }
    isnomore = true;
    }
    previousTotal = getLayoutManager().getItemCount();*/
    }

取消正式发布版本的日志打印

正式发布的版本存在一些 在下拉时的调试打印,希望这下可以在发布时删除掉,还有就是loadMoreComplete的作用最好和noMoreLoading分开或者改一些比较容易区分的名字,现在很容易弄错。

设置没有更多数据状态

您好,大神,刚刚下载了您的源码,非常赞,不过我没有找到在哪里设置没有更多数据的方法,比如共3页数据,第3页数据加载完毕后,怎么设置没有数据无法加载更多状态了呢?

瀑布流布局错位

瀑布流布局的时候,item 的布局必须是线性水平方向的如果是vertical的话,如果个数是单个的话,最后一个是从右边开始的,不是从左边开始的

minsdk问题

可以将库文件的最小sdk设置到8么?目前库minsdk是11, 2.0+的系统无法使用,谢谢!

XRecyclerView改成水平显示无法隐藏上拉和下拉布局

通过属性设置成水平显示
GridLayoutManager layoutManager = new GridLayoutManager(this.context,3);
layoutManager.setOrientation(GridLayoutManager.HORIZONTAL);
然后在使用.setLoadingMoreEnabled(false);setPullRefreshEnabled(false);屏蔽之后仍然会占用地方。
垂直显示正常

嘿,写的很棒,给个建议哈

因为之前自己有封装过类似的View,用作者你的这个View,有些地方不方便,就是如果开放设置几种View的状态,
一 下拉刷新
二 加载更多
三 下拉刷新+加载更多
然后 各自的回调不变,不必在单独设置一些方法

滑动不流畅

有头部的时候,当头部有一半出现在屏幕上时,向下滑动不了

BUG:adapter.notifyItemXX(position),刷新位置不对

  • XRecyclerView的头部刷新和底部加载更多通过在WrapAdapter使用mHeaderViews和mFootViews作为数据实现,而mDataObserver没有对这两个数据做判断处理,因此造成刷新位置不对,应该改成如下形式:
private final RecyclerView.AdapterDataObserver mDataObserver = new RecyclerView.AdapterDataObserver() {
        @Override
        public void onChanged() {
            mWrapAdapter.notifyDataSetChanged();
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            positionStart+=mHeaderViews.size();
            mWrapAdapter.notifyItemRangeInserted(positionStart, itemCount);
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount) {
            positionStart+=mHeaderViews.size();
            mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount);
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
            positionStart+=mHeaderViews.size();
            mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount, payload);
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            positionStart+=mHeaderViews.size();
            mWrapAdapter.notifyItemRangeRemoved(positionStart, itemCount);
        }

        @Override
        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            fromPosition+=mHeaderViews.size();
            mWrapAdapter.notifyItemMoved(fromPosition, toPosition);
        }
    };

经常崩溃,崩溃错误如下

Caused by: java.lang.IllegalArgumentException: called detach on an already detached child ViewHolder{29d69d05 position=3 id=-1, oldPos=-1, pLpos:-1 scrap tmpDetached no parent}
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.support.v7.widget.RecyclerView$4.detachViewFromParent(RecyclerView.java:605)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.support.v7.widget.ChildHelper.detachViewFromParent(ChildHelper.java:284)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.support.v7.widget.RecyclerView$LayoutManager.detachViewInternal(RecyclerView.java:6473)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.support.v7.widget.RecyclerView$LayoutManager.detachViewAt(RecyclerView.java:6466)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.support.v7.widget.RecyclerView$LayoutManager.scrapOrRecycleView(RecyclerView.java:6835)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.support.v7.widget.RecyclerView$LayoutManager.detachAndScrapAttachedViews(RecyclerView.java:6818)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:532)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2847)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3145)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.view.View.layout(View.java:16542)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.view.ViewGroup.layout(ViewGroup.java:5302)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1076)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.view.View.layout(View.java:16542)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.view.ViewGroup.layout(ViewGroup.java:5302)
03-02 12:51:27.944 4119-4119/E/AndroidRuntime: at android.widget.LinearLayout.setChildFrame(LinearLayout.java:2102)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1956)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.widget.LinearLayout.onLayout(LinearLayout.java:1865)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.view.View.layout(View.java:16542)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.view.ViewGroup.layout(ViewGroup.java:5302)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1627)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.view.View.layout(View.java:16542)
03-02 12:51:27.944 4119-4119/com.babytree.apps.pregnancy E/AndroidRuntime: at android.view.ViewGroup.layout(ViewGroup.java:5302)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.widget.LinearLayout.setChildFrame(LinearLayout.java:2102)
03-02 12:51:27.944 4119-4119 E/AndroidRuntime: at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1956)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.widget.LinearLayout.onLayout(LinearLayout.java:1865)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.view.View.layout(View.java:16542)
03-02 12:51:27.944 4119-4119/com.babytree.apps.pregnancy E/AndroidRuntime: at android.view.ViewGroup.layout(ViewGroup.java:5302)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.widget.LinearLayout.setChildFrame(LinearLayout.java:2102)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1956)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.widget.LinearLayout.onLayout(LinearLayout.java:1865)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.view.View.layout(View.java:16542)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.view.ViewGroup.layout(ViewGroup.java:5302)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.widget.FrameLayout.onLayout(FrameLayout.java:508)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.view.View.layout(View.java:16542)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.view.ViewGroup.layout(ViewGroup.java:5302)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1076)
03-02 12:51:27.944 4119-4119/ E/AndroidRuntime: at android.view.View.layout(View.java:16542)

各种小bug,这是我另开一个的原因

上拉刷新的时候,滚动到底部,刷新完成会不能滚动,目前只发现瀑布流会出现,建议刷新完成后滚动到第一个item,这样就不会出现问题了,还有刷新时间也一直会显示刚刚,太鸡肋,而且时间显示不能够用代码设置,建议转成上次刷新的年月日,这样更清楚点

BUG-有时会无法上下滑动列表

下拉刷新,在刷新过程中将列表推上去,让展示刷新动画的头布局移出屏幕,推之后不要做任何操作,等待刷新成功,数据更新成功说明刷新操作执行完毕,此时再滑动列表会发生无法滑动的情况。ListView和GridView都有这种问题。

当第一个header出现的时候,上下滑根本滑动不了

当第一个header出现的时候,上下滑根本滑动不了,经过简单的修改就可以了。
private boolean isOnTop() {
if (mHeaderViews == null || mHeaderViews.isEmpty()) {
return false;
}

    View view = mHeaderViews.get(0);
    if (view.getParent() != null) {
        return true;
    } else {
        return false;
    }

// LayoutManager layoutManager = getLayoutManager();
// int firstVisibleItemPosition;
// if (layoutManager instanceof GridLayoutManager) {
// firstVisibleItemPosition = ((GridLayoutManager) layoutManager).findFirstVisibleItemPosition();
// } else if (layoutManager instanceof StaggeredGridLayoutManager) {
// int[] into = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
// ((StaggeredGridLayoutManager) layoutManager).findFirstVisibleItemPositions(into);
// firstVisibleItemPosition = findMin(into);
// } else {
// firstVisibleItemPosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
// }
// if (firstVisibleItemPosition < 1) {
// return true;
// }
// return false;
}

加载更多逻辑好像有误

在加载更多失败的回调中调用loadMoreComplete(),之后就是最后会有 “没有更多了”那一条item。
但其实是因为网络原因。

GridLayoutManager问题

这个LinearLayoutManager布局好用
但是设置成GridLayoutManager布局后,显示有问题

展示出来的列表布局很小

展示出来的列表布局很小,数据都读出来了,布局也对,就是很小,控制台报No adapter attached; skipping layout

onItemRangeMoved 索引bug

没有加上head数量,回调时返回的索引会包含head的数量,也就是索引不从 0 开始

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.