自定义RecyclerView实现下拉刷新和上拉加载

通过导入第三方库实现ListView的上拉加载和下拉刷新比较简单,今天我要讲的是自定义RecyclerView实现下拉刷新和上拉加载。首先,自定义下拉刷新上拉加载是通过给RecyclerView添加头部和尾部实现的。而问题是RecyclerView并没有addHeaderView(View v)和addFooterView(View v)方法。

     第一步:自定义HeaderAndFooterWrapper(装饰者模式)实现给RecyclerView添加头部和尾部
    方法:public void addHeaderView(View v)
              public void addFooterView(View v)
     代码参照张鸿洋:Android 优雅的为RecyclerView添加HeaderView和FooterView 
     链接:http://blog.csdn.net/lmj623565791/article/details/51854533

      第二步:定义类RefreshRecyclerView并抽取为库

1) 头部布局:refresh_recyclerview_header.xml

 
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <!--下拉刷新控件-->

  3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

  4. android:layout_width="match_parent"

  5. android:layout_height="wrap_content"

  6. android:gravity="center"

  7. android:orientation="horizontal">

  8.  
  9. <FrameLayout

  10. android:layout_width="wrap_content"

  11. android:layout_height="wrap_content"

  12. android:padding="10dp">

  13.  
  14. <ImageView

  15. android:id="@+id/iv_header_refresh"

  16. android:layout_width="wrap_content"

  17. android:layout_height="wrap_content"

  18. android:layout_gravity="center"

  19. android:src="@drawable/headview_red_arrow" />

  20.  
  21. <ProgressBar

  22. android:id="@+id/pb_header_refresh"

  23. android:layout_width="wrap_content"

  24. android:layout_height="wrap_content"

  25. android:layout_gravity="center"

  26. android:indeterminateDrawable="@drawable/custom_progressbar"

  27. android:visibility="gone" />

  28. </FrameLayout>

  29.  
  30. <LinearLayout

  31. android:layout_width="wrap_content"

  32. android:layout_height="wrap_content"

  33. android:layout_gravity="center_vertical"

  34. android:orientation="vertical">

  35.  
  36. <TextView

  37. android:id="@+id/tv_status"

  38. android:layout_width="match_parent"

  39. android:layout_height="wrap_content"

  40. android:gravity="center_horizontal"

  41. android:text="下拉刷新"

  42. android:textColor="#ff0000"

  43. android:textSize="18sp" />

  44.  
  45. <TextView

  46. android:id="@+id/tv_time"

  47. android:layout_width="match_parent"

  48. android:layout_height="wrap_content"

  49. android:layout_marginTop="5dp"

  50. android:gravity="center_horizontal"

  51. android:text="上次更新时间:2016-10-31"

  52. android:textColor="#55000000"

  53. android:textSize="16sp" />

  54.  
  55. </LinearLayout>

  56.  
  57. </LinearLayout>


 

2)尾部布局(上拉加载部分):refresh_recyclerview_footer.xml

 
  1. <span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>

  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

  3. android:layout_width="match_parent"

  4. android:gravity="center"

  5. android:layout_height="wrap_content"

  6. android:orientation="horizontal">

  7. <ProgressBar

  8. android:indeterminateDrawable="@drawable/custom_progressbar"

  9. android:layout_margin="5dp"

  10. android:layout_width="wrap_content"

  11. android:layout_height="wrap_content" />

  12. <TextView

  13. android:text="加载更多中...."

  14. android:textColor="#ff0000"

  15. android:textSize="25sp"

  16. android:layout_marginLeft="10dp"

  17. android:layout_width="wrap_content"

  18. android:layout_height="wrap_content" />

  19. </LinearLayout></span>



3)自定义ProgressBar样式custom_progressbar.xml

 
  1. <span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>

  2. <rotate xmlns:android="http://schemas.android.com/apk/res/android"

  3. android:fromDegrees="0"

  4. android:toDegrees="360"

  5. android:pivotX="50%"

  6. android:pivotY="50%">

  7. <shape android:shape="ring"

  8. android:innerRadiusRatio="2.5"

  9. android:thicknessRatio="15"

  10. android:useLevel="false"

  11. >

  12. <gradient android:startColor="#ff0000"

  13. android:endColor="#ffffff"

  14. android:centerColor="#88ff0000"

  15. android:type="sweep"></gradient>

  16. </shape>

  17. </rotate></span>

代码如下:
 

 
  1. public class RefreshRecyclerView extends RecyclerView {

  2.  
  3. private final Context mContext;

  4. // 顶部视图,下拉刷新控件

  5. private LinearLayout headerView;

  6. // 正在刷新状态的进度条

  7. private ProgressBar pb_header_refresh;

  8. // 刷新箭头

  9. private ImageView iv_header_refresh;

  10. // 显示刷新状态

  11. private TextView tv_status;

  12. // 显示最近一次的刷新时间

  13. private TextView tv_time;

  14. // 转到下拉刷新状态时的动画

  15. private RotateAnimation downAnima;

  16. // 转到释放刷新状态时的动画

  17. private RotateAnimation upAnima;

  18. //触摸事件中按下的Y坐标,初始值为-1,为防止ACTION_DOWN事件被抢占

  19. private float startY = -1;

  20. // 下拉刷新控件的高度

  21. private int pulldownHeight;

  22. // 刷新状态:下拉刷新

  23. private final int PULL_DOWN_REFRESH = 0;

  24. // 刷新状态:释放刷新

  25. private final int RELEASE_REFRESH = 1;

  26. // 刷新状态:正常刷新

  27. private final int REFRESHING = 2;

  28.  
  29. // 当前头布局的状态-默认为下拉刷新

  30. private int currState = PULL_DOWN_REFRESH;

  31. //

  32. private RefreshRecyclerView.OnRefreshListener mOnRefreshListener;

  33. // 尾部视图

  34. private View footerView;

  35. // 尾部试图(上拉加载控件)的高度

  36. private int footerViewHeight;

  37. // 判断是否是加载更多

  38. private boolean isLoadingMore;

  39.  
  40. public RefreshRecyclerView(Context context) {

  41. this(context, null);

  42. }

  43.  
  44. public RefreshRecyclerView(Context context, AttributeSet attrs) {

  45. this(context, attrs, 0);

  46. }

  47.  
  48. public RefreshRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {

  49. super(context, attrs, defStyleAttr);

  50. mContext = context;

  51. initHeaderView();

  52. initFooterView();

  53. }

  54. /**

  55. * 返回尾部布局,供外部调用

  56. * @return

  57. */

  58. public View getFooterView(){

  59. return footerView;

  60. }

  61. /**

  62. * 返回头部布局,供外部调用

  63. * @return

  64. */

  65. public View getHeaderView(){

  66. return headerView;

  67. }

  68.  
  69. /**

  70. * 通过HeaderAndFooterWrapper对象给RecyclerView添加尾部

  71. * @param footerView 尾部视图

  72. * @param headerAndFooterWrapper RecyclerView.Adapter的包装类对象,通过它给RecyclerView添加尾部视图

  73. */

  74. public void addFooterView(View footerView, HeaderAndFooterWrapper headerAndFooterWrapper) {

  75. headerAndFooterWrapper.addFooterView(footerView);

  76. }

  77.  
  78. /**

  79. * 通过HeaderAndFooterWrapper对象给RecyclerView添加头部部

  80. * @param headerView 尾部视图

  81. * @param headerAndFooterWrapper RecyclerView.Adapter的包装类对象,通过它给RecyclerView添加头部视图

  82. */

  83. public void addHeaderView(View headerView,HeaderAndFooterWrapper headerAndFooterWrapper) {

  84. headerAndFooterWrapper.addHeaderView(headerView);

  85. }


 

 

初始化头部布局和尾部布局

 
  1. private void initHeaderView() {

  2. headerView = (LinearLayout) View.inflate(mContext, R.layout.refresh_recyclerview_header, null);

  3. tv_time = (TextView) headerView.findViewById(R.id.tv_time);

  4. tv_status = (TextView) headerView.findViewById(R.id.tv_status);

  5. iv_header_refresh = (ImageView) headerView.findViewById(R.id.iv_header_refresh);

  6. pb_header_refresh = (ProgressBar) headerView.findViewById(R.id.pb_header_refresh);

  7. headerView.measure(0, 0);

  8. pulldownHeight = headerView.getMeasuredHeight();

  9. headerView.setPadding(0, -pulldownHeight, 0, 0);

  10. //初始化头部布局的动画

  11. initAnimation();

  12. }

  13. /**

  14. * 刷新状态改变时的动画

  15. */

  16. private void initAnimation() {

  17. // 从下拉刷新状态转换为释放刷新状态

  18. upAnima = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

  19. upAnima.setFillAfter(true);

  20. upAnima.setDuration(500);

  21. // 转到下拉刷新的动画

  22. downAnima = new RotateAnimation(-180, -360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

  23. downAnima.setFillAfter(true);

  24. downAnima.setDuration(500);

  25. }

  26.  
 
 
  1. private void initFooterView() {

  2. footerView = View.inflate(mContext, R.layout.refresh_recyclerview_footer, null);

  3. footerView.measure(0, 0);

  4. //得到控件的高

  5. footerViewHeight = footerView.getMeasuredHeight();

  6. //默认隐藏下拉刷新控件

  7. // View.setPadding(0,-控件高,0,0);//完全隐藏

  8. //View.setPadding(0, 0,0,0);//完全显示

  9. footerView.setPadding(0, -footerViewHeight, 0, 0);

  10. // addFooterView(footerView);

  11. // 自己监听自己

  12. this.addOnScrollListener(new MyOnScrollListener());

  13. }

 
重写onTouchEvent()方法,startY表示按下时的坐标,但是有可能ACTION_DOWN事件被强占,那么case MotionEvent.ACTION_DOWN:就没机会执行。所以case MotionEvent.ACTION_MOVE:子句时首先判断startY是否为-1,是的话把第一次移动的坐标当作按下时的坐
标。然后判断当前的状态,如果正在刷新就不必再次执行下面的刷新代码,直接跳出。dY>0表示用户正在执行下拉操作,因为头部视图初始坐标为-pulldownHeight,所以手指在屏幕上滑动多少距离,顶部视图的y坐标就应该增加相应值。paddingTop==0是一个状态
分界线,paddingTop < 0 是下拉刷新状态,大于0是释放刷新状态。根据paddingTop的值跳转相应的状态。最后在手指抬起的时候,首先重置startY = -1;然后判断刷新状态,如果是下拉刷新(头部视图没有完全显示)就设置下拉控件为默认隐藏状态,如果是释放
刷新状态(paddingTop > 0),就跳转到正在刷新状态,并让下拉控件完全显示同时调用用户的回调事件,刷新页面数据。
 
  1. @Override

  2. public boolean onTouchEvent(MotionEvent ev) {

  3. switch (ev.getAction()) {

  4. case MotionEvent.ACTION_DOWN:

  5. startY = ev.getY();

  6. break;

  7. case MotionEvent.ACTION_MOVE:

  8. //防止ACTION_DOWN事件被抢占,没有执行

  9. if (startY == -1) {

  10. startY = ev.getY();

  11. }

  12. float endY = ev.getY();

  13. float dY = endY - startY;

  14. //判断当前是否正在刷新中

  15. if (currState == REFRESHING) {

  16. //如果当前是正在刷新,不执行下拉刷新了,直接break;

  17. break;

  18. }

  19. // 如果是下拉

  20. if (dY > 0) {

  21. int paddingTop = (int) (dY - pulldownHeight);

  22. if (paddingTop > 0 && currState != RELEASE_REFRESH) {

  23. //完全显示下拉刷新控件,进入松开刷新状态

  24. currState = RELEASE_REFRESH;

  25. refreshViewState();

  26. } else if (paddingTop < 0 && currState != PULL_DOWN_REFRESH) {

  27. //没有完全显示下拉刷新控件,进入下拉刷新状态

  28. currState = PULL_DOWN_REFRESH;

  29. refreshViewState();

  30. }

  31. headerView.setPadding(0, paddingTop, 0, 0);

  32. }

  33. break;

  34. case MotionEvent.ACTION_UP:

  35. //5.重新记录值

  36. startY = -1;

  37. if (currState == PULL_DOWN_REFRESH) {

  38. //设置默认隐藏

  39. headerView.setPadding(0, -pulldownHeight, 0, 0);

  40. } else if (currState == RELEASE_REFRESH) {

  41. //当前是释放刷新,进入到正在刷新状态,完全显示

  42. currState = REFRESHING;

  43. refreshViewState();

  44. headerView.setPadding(0, 0, 0, 0);

  45. //调用用户的回调事件,刷新页面数据

  46. if (mOnRefreshListener != null) {

  47. mOnRefreshListener.onPullDownRefresh();

  48. }

  49. }

  50. break;

  51. }

  52. return super.onTouchEvent(ev);

  53. }

  54. /**

  55. * 跳转刷新状态

  56. */

  57. private void refreshViewState() {

  58. switch (currState) {

  59. // 跳转到下拉刷新

  60. case PULL_DOWN_REFRESH:

  61. iv_header_refresh.startAnimation(downAnima);

  62. tv_status.setText("下拉刷新");

  63. break;

  64. // 跳转到释放刷新

  65. case RELEASE_REFRESH:

  66. iv_header_refresh.startAnimation(upAnima);

  67. tv_status.setText("释放刷新");

  68. break;

  69. // 跳转到正在刷新

  70. case REFRESHING:

  71. iv_header_refresh.clearAnimation();

  72. iv_header_refresh.setVisibility(GONE);

  73. pb_header_refresh.setVisibility(VISIBLE);

  74. tv_status.setText("正在刷新中.....");

  75. break;

  76. }

  77. }

 

定义接口

 
  1. /**

  2. * 定义下拉刷新和上拉加载的接口

  3. */

  4. public interface OnRefreshListener {

  5. /**

  6. * 当下拉刷新时触发此方法

  7. */

  8. void onPullDownRefresh();

  9.  
  10. /**

  11. * 当加载更多的时候回调这个方法

  12. */

  13. void onLoadingMore();

  14.  
  15. }

  16. public void setOnRefreshListener(RefreshRecyclerView.OnRefreshListener listener) {

  17. this.mOnRefreshListener = listener;

  18. }

  19.  
  20. /**

  21. * 当刷新完数据之后,调用此方法,把头文件隐藏,并且状态设置为初始状态

  22. * @param isSuccess

  23. */

  24. public void onFinishRefresh(boolean isSuccess) {

  25. if (isLoadingMore) {

  26. footerView.setPadding(0, -footerViewHeight, 0, 0);

  27. isLoadingMore = false;

  28. } else {

  29. headerView.setPadding(0, -pulldownHeight, 0, 0);

  30. currState = PULL_DOWN_REFRESH;

  31. iv_header_refresh.setVisibility(VISIBLE);

  32. pb_header_refresh.setVisibility(GONE);

  33. tv_status.setText("下拉刷新");

  34. if (isSuccess) {

  35. //设置更新时间

  36. tv_time.setText(getSystemTime());

  37. }

  38. }

  39. }

  40.  
  41. private String getSystemTime() {

  42. SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

  43. return dateFormat.format(new Date());

  44. }

 
 

上拉加载逻辑的实现,重写onScrollStateChanged()方法。如果newState为空闲状态或者是快速滑动状态就判断RecyclerView的最后一个可见Item的索引是否 >= getChildCount()-1。是的话就触发加载更多事件,完全显示上拉加载控件并调用回调事件。这里要注意:ListView是SCROLL_STATE_FLING而RecyclerView是SCROLL_STATE_SETTLING,ListView得到最后一个可见Item索引直接

getLastVisiblePosition()方法就行了。RecyclerView比较麻烦:首先要判断布局管理器是否是线性布局管理器,因为只有LinearLayoutManager才有查找第一个和最后一个可见View位置的方法。
 
 
  1. private class MyOnScrollListener extends OnScrollListener {

  2. @Override

  3. public void onScrollStateChanged(RecyclerView recyclerView, int newState) {

  4. // super.onScrollStateChanged(recyclerView, newState);

  5. if (newState == SCROLL_STATE_IDLE || newState == SCROLL_STATE_SETTLING) {

  6. //判断是当前layoutManager是否为LinearLayoutManager

  7. // 只有LinearLayoutManager才有查找第一个和最后一个可见view位置的方法

  8. LayoutManager layoutManager = recyclerView.getLayoutManager();

  9. if (layoutManager instanceof LinearLayoutManager) {

  10. LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;

  11. //当停止滚动时或者惯性滚动时,RecyclerView的最后一个显示的条目:getCount()-1

  12. // 注意是findLastVisibleItemPosition()而不是getLastVisiblePosition

  13. if (linearLayoutManager.findLastVisibleItemPosition() >= getChildCount() - 1) {

  14. isLoadingMore = true;

  15. //把底部加载显示

  16. footerView.setPadding(0, 0, 0, 0);

  17. if (mOnRefreshListener != null) {

  18. mOnRefreshListener.onLoadingMore();

  19. }

  20. }

  21. }

  22. }

  23. }

  24. }


     第三步:使用 自定义的RecyclerView
首先上布局

 
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

  3. android:layout_width="match_parent"

  4. android:layout_height="match_parent"

  5. android:orientation="vertical">

  6.  
  7. <com.example.refreshrecyclerview_library.RefreshRecyclerView

  8. android:id="@+id/custom_recyclerview"

  9. android:layout_width="match_parent"

  10. android:layout_height="0dp"

  11. android:layout_weight="1"

  12. android:cacheColorHint="@android:color/transparent"

  13. android:divider="@null"

  14. android:fadingEdge="none" />

  15.  
  16. </LinearLayout>


测试代码

 
  1. public class MainActivity extends Activity {

  2.  
  3.  
  4. private static final int REFRESH = 0;

  5. private static final int LOADMORE = 1;

  6. private HeaderAndFooterWrapper headerAndFooterWrapper;

  7. private RefreshRecyclerViewAdapter recyclerAdapter;

  8. private RefreshRecyclerView custom_recyclerview;

  9. private Handler handler = new Handler(){

  10. public void handleMessage(Message msg){

  11. switch (msg.what) {

  12. case REFRESH:

  13. custom_recyclerview.onFinishRefresh(true);

  14. break;

  15. case LOADMORE:

  16. custom_recyclerview.onFinishRefresh(false);

  17. break;

  18. }

  19. }

  20. };

  21. @Override

  22. protected void onCreate(Bundle savedInstanceState) {

  23. super.onCreate(savedInstanceState);

  24. setContentView(R.layout.activity_main);

  25. custom_recyclerview = (RefreshRecyclerView) findViewById(R.id.custom_recyclerview);

  26. initRefreshRecyclerView();

  27. }

  28.  
  29. private void initRefreshRecyclerView() {

  30. // 给Recycler设置分割线

  31. custom_recyclerview.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));

  32. recyclerAdapter = new RefreshRecyclerViewAdapter(this);

  33. headerAndFooterWrapper = new HeaderAndFooterWrapper(recyclerAdapter);

  34. // 不要忘记设置布局管理器

  35. custom_recyclerview.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));

  36. custom_recyclerview.setAdapter(headerAndFooterWrapper);

  37. custom_recyclerview.addHeaderView(custom_recyclerview.getHeaderView(), headerAndFooterWrapper);

  38. custom_recyclerview.addFooterView(custom_recyclerview.getFooterView(), headerAndFooterWrapper);

  39. custom_recyclerview.setOnRefreshListener(new OnRecyclerRefreshListener());

  40. }

  41.  
  42. private class OnRecyclerRefreshListener implements RefreshRecyclerView.OnRefreshListener {

  43. @Override

  44. public void onPullDownRefresh() {

  45. // 执行下拉刷新操作,一般是联网更新数据

  46. new Thread(new Runnable() {

  47. @Override

  48. public void run() {

  49. SystemClock.sleep(2000);

  50. handler.sendEmptyMessage(REFRESH);

  51. }

  52. }).start();

  53. }

  54.  
  55. @Override

  56. public void onLoadingMore() {

  57. // 执行上拉加载操作,一般是联网请求更多分页数据

  58. new Thread(new Runnable() {

  59. @Override

  60. public void run() {

  61. SystemClock.sleep(2000);

  62. handler.sendEmptyMessage(LOADMORE);

  63. }

  64. }).start();

  65. }

  66. }

  67. }

  68. <pre name="code" class="java">

  69. public class RefreshRecyclerViewAdapter extends RecyclerView.Adapter<RefreshRecyclerViewAdapter.ViewHolder> {

  70.  
  71. private Context mContext;

  72. private List<String> datas;

  73.  
  74. public RefreshRecyclerViewAdapter(Context mContext) {

  75. this.mContext = mContext;

  76. datas = new ArrayList<>();

  77. for(int i = 1; i <= 20; i++) {

  78. datas.add("我是Content :"+i);

  79. }

  80. }

  81.  
  82. @Override

  83. public RefreshRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

  84.  
  85. View convertView = View.inflate(mContext, R.layout.item_recycler, null);

  86. return new ViewHolder(convertView);

  87. }

  88.  
  89. @Override

  90. public void onBindViewHolder(RefreshRecyclerViewAdapter.ViewHolder holder, final int position) {

  91. String data = datas.get(position);

  92. holder.tv_content.setText(data);

  93. }

  94.  
  95. @Override

  96. public int getItemCount() {

  97. return datas.size();

  98. }

  99.  
  100. public class ViewHolder extends RecyclerView.ViewHolder {

  101.  
  102. TextView tv_content;

  103.  
  104. public ViewHolder(final View itemView) {

  105. super(itemView);

  106. tv_content = (TextView) itemView.findViewById(R.id.tv);

  107. }

  108. }

  109. }


 

 

这里还用到一个分割线的类,RecyclerView默认是没有分割线的,这段代码可以直接粘贴使用

 
  1. public class DividerItemDecoration extends RecyclerView.ItemDecoration {

  2.  
  3. public final static int VERTICAL_LIST = LinearLayoutManager.VERTICAL;

  4. public final static int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;

  5. private int mOrientation;

  6. private Drawable mDivider;

  7. private static final int[] ATTRS = new int[]{android.R.attr.listDivider};

  8.  
  9. public DividerItemDecoration(Context context, int mOrientation) {

  10. final TypedArray a = context.obtainStyledAttributes(ATTRS);

  11. mDivider = a.getDrawable(0);

  12. a.recycle();

  13. setOrientation(mOrientation);

  14.  
  15. }

  16.  
  17. private void setOrientation(int mOrientation) {

  18. if (mOrientation != VERTICAL_LIST && mOrientation != HORIZONTAL_LIST) {

  19. throw new IllegalArgumentException("Invalid orientation");

  20. } else {

  21. this.mOrientation = mOrientation;

  22. }

  23. }

  24.  
  25. @Override

  26. public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {

  27. super.onDraw(c, parent, state);

  28. if (mOrientation == VERTICAL_LIST) {

  29. drawVertical(c, parent);

  30. } else if (mOrientation == HORIZONTAL_LIST) {

  31. drawHorizontal(c, parent);

  32. }

  33. }

  34.  
  35. private void drawVertical(Canvas c, RecyclerView parent) {

  36. int left = parent.getPaddingLeft();

  37. int right = parent.getWidth() - parent.getPaddingRight();

  38. int childCount = parent.getChildCount();

  39. for (int i = 0; i < childCount; i++) {

  40. View child = parent.getChildAt(i);

  41. RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

  42. int top = child.getBottom() + params.bottomMargin;

  43. int bottom = top + mDivider.getIntrinsicHeight();

  44. mDivider.setBounds(left, top, right, bottom);

  45. mDivider.draw(c);

  46. }

  47. }

  48.  
  49. private void drawHorizontal(Canvas c, RecyclerView parent) {

  50. int top = parent.getPaddingTop();

  51. int bottom = parent.getHeight() - parent.getPaddingBottom();

  52. int childCount = parent.getChildCount();

  53. for (int i = 0; i < childCount; i++) {

  54. View child = parent.getChildAt(i);

  55. RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

  56. int left = child.getRight() + params.rightMargin;

  57. int right = left + mDivider.getIntrinsicHeight();

  58. mDivider.setBounds(left,top,right,bottom);

  59. mDivider.draw(c);

  60. }

  61.  
  62. }

  63.  
  64. @Override

  65. public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {

  66. // super.getItemOffsets(outRect, view, parent, state);

  67. if(mOrientation == VERTICAL_LIST) {

  68. outRect.set(0,0,0,mDivider.getIntrinsicHeight());

  69. }else{

  70. outRect.set(0,0,mDivider.getIntrinsicHeight(),0);

  71. }

  72. }

  73. }

猜你喜欢

转载自blog.csdn.net/suyimin2010/article/details/81256614