国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

android教你打造獨一無二的上拉下拉刷新加載框架

2019-12-12 03:19:50
字體:
供稿:網(wǎng)友

其實早在去年七月,群里小伙伴就有讓我共享這個。但我當(dāng)時絕的技術(shù)不純熟。代碼有bug什么的。沒有寫出來。現(xiàn)在感覺整理的差不多了。就寫出來讓大家看看,有問題一起討論解決。

說到刷新加載,我們第一個想到啥,對了就是swiperefreshlayout,還有什么SuperSwiperefreshlayout,XRecyclerView等等。反正老多了,我還是之前那句話,不管用什么,我們需要知道他的原理。

打造框架開始

對于刷新加載的實現(xiàn),你們第一個想到的是什么?是用swiperefresh然后在recyclerview底部加一個不同type?還是用事件攔截呢?那必須是事件攔截啊,雖然現(xiàn)在swiperefreshlayout很火,基本很多app都能看到他。但是遇到那種坑比公司說刷新要用自己公司logo你也沒轍。對把。。好了,感覺得罪了好多公司,不管他,我們繼續(xù)。

我們先看下我們的效果圖:

老鐵,沒毛病。下面我介紹如何實現(xiàn)的。

下拉刷新

首先我們給出如下幾個參數(shù),后面要用:

  private NestedScrollingParentHelper helper = null;  private boolean IsRefresh = true;  private boolean IsLoad = true;  //滑動的總距離  private int totalY = 0;  private LinearLayout headerLayout = null;  private MyRecyclerView myRecyclerView = null;  private LinearLayout footerLayout = null;

既然是刷新,我們的滾動肯定是在父view之前的。所以我們需要在onNestedPreScroll這個方法里面寫上我們所需要改動的x,y值。

我們需要用父view去攔截它。

我們需要判斷dy的值是否大于0,因為大于0是刷新操作,小于0是加載操作。然后我們需要判斷recyclerview是否是縱向的而不是橫向的。

public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {    if (IsRefresh) {      if (dy > 0) {        if (myRecyclerView.isOrientation(0)) {          totalY += dy;          if ((totalY / 2) <= 0) {            scrollTo(0, totalY / 2);            consumed[1] = dy;          } else {            scrollTo(0, 0);            consumed[1] = 0;          }        }        return;      }    }

上拉加載

上面我也說了onNestedPreScroll這個方法中判斷dy<0才是加載操作。所以綜上所述,代碼變成了這樣:

 public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {    if (totalY < 0 && myRecyclerView.isOrientation(0) || totalY > 0 && myRecyclerView.isOrientation(1)) {      isfling = true;    }    if (IsRefresh) {      if (dy > 0) {        if (myRecyclerView.isOrientation(0)) {          totalY += dy;          if ((totalY / 2) <= 0) {            scrollTo(0, totalY / 2);            consumed[1] = dy;          } else {            scrollTo(0, 0);            consumed[1] = 0;          }        }        return;      }    }    if (IsLoad) {      if (dy < 0) {        if (myRecyclerView.isOrientation(1)) {          totalY += dy;          if ((totalY / 2) >= 0) {            scrollTo(0, totalY / 2);            consumed[1] = dy;          } else {            scrollTo(0, 0);            consumed[1] = 0;          }        }        return;      }    }  }

最后我們需要在子view滑動結(jié)束后,實行如下操作:

 //子view滑動結(jié)束調(diào)用  //dyUnconsumed < 0 向下滾  //dyUnconsumed > 0 向上滾  public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {    if (dyUnconsumed != 0) {      totalY += dyUnconsumed;      scrollTo(0, totalY / 2);    }  }

其實最主要的兩個方法已經(jīng)解決了,其他到?jīng)]什么了,這邊,我把nestedscrolling的8個接口的功能和自定義recyclerview放出來。已變大家參考。希望大家都能實現(xiàn)自己的刷新加載。告別swiperefreshlayout。

添加header和footer

這里我們參考listview自帶的addheaderview和addfooterview。代碼如下:

 public void addHeaderView(View headerView, int headerHeight) {    this.headerLayout.removeAllViews();    this.headerLayout.addView(headerView);    LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, headerHeight);    layoutParams.topMargin = -headerHeight;    this.headerLayout.setLayoutParams(layoutParams);  }  public void addFooterView(View footerView, int footerHeight) {    this.footerLayout.removeAllViews();    this.footerLayout.addView(footerView);    this.footerLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, footerHeight));  }

幾個接口的實現(xiàn)

 public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {    return true;  }  public void onNestedScrollAccepted(View child, View target, int axes) {    helper.onNestedScrollAccepted(child, target, axes);  }  //父view攔截子view的滾動  public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {    if (totalY < 0 && myRecyclerView.isOrientation(0) || totalY > 0 && myRecyclerView.isOrientation(1)) {      isfling = true;    }    if (IsRefresh) {      if (dy > 0) {        if (myRecyclerView.isOrientation(0)) {          totalY += dy;          if ((totalY / 2) <= 0) {            scrollTo(0, totalY / 2);            consumed[1] = dy;          } else {            scrollTo(0, 0);            consumed[1] = 0;          }        }        return;      }    }    if (IsLoad) {      if (dy < 0) {        if (myRecyclerView.isOrientation(1)) {          totalY += dy;          if ((totalY / 2) >= 0) {            scrollTo(0, totalY / 2);            consumed[1] = dy;          } else {            scrollTo(0, 0);            consumed[1] = 0;          }        }        return;      }    }  }  //子view滑動結(jié)束調(diào)用  //dyUnconsumed < 0 向下滾  //dyUnconsumed > 0 向上滾  public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {    if (dyUnconsumed != 0) {      totalY += dyUnconsumed;      scrollTo(0, totalY / 2);    }  }  public void onStopNestedScroll(View child) {    helper.onStopNestedScroll(child);    if (onTouchUpListener != null) {      isfling = false;      onTouchUpListener.touchUp();    }  }  public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {    return isfling;  }  public boolean onNestedPreFling(View target, float velocityX, float velocityY) {    return isfling;  }  public int getNestedScrollAxes() {    return helper.getNestedScrollAxes();  }

自定義recyclerview

既然是自己寫的刷新加載框架,總不能還有自定義layout中在放個recyclerview。多麻煩,自定義一個,直接放在里面,然后分別放個header和footer 就沒必要每次有頁面用到刷新都要寫一個布局。3個布局解決整個項目的刷新和加載。話不多說,代碼如下:

  private class MyRecyclerView extends RecyclerView {    private StaggeredGridLayoutManager staggeredGridLayoutManager = null;    private LinearLayoutManager linearLayoutManager = null;    private GridLayoutManager gridLayoutManager = null;    private boolean isScrollLoad = false;    private boolean isScrollRefresh = false;    public MyRecyclerView(Context context) {      super(context);      setVerticalFadingEdgeEnabled(false);      setHorizontalFadingEdgeEnabled(false);      setVerticalScrollBarEnabled(false);      setHorizontalScrollBarEnabled(false);      setOverScrollMode(OVER_SCROLL_NEVER);      setItemAnimator(new DefaultItemAnimator());    }    private void setMyLayoutManager(LayoutManager layoutManager) {      if (layoutManager instanceof StaggeredGridLayoutManager) {        staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;      } else if (layoutManager instanceof GridLayoutManager) {        gridLayoutManager = (GridLayoutManager) layoutManager;      } else if (layoutManager instanceof LinearLayoutManager) {        linearLayoutManager = (LinearLayoutManager) layoutManager;      }      setLayoutManager(layoutManager);      if (!isVertical()) {        throw new NullPointerException("vertical!");      }    }    private boolean isOrientation(int orientation) {//orientation,0代表向下,1代表向上      if (orientation == 0)        return isCanPullDown();      else if (orientation == 1)        return isCanPullUp();      return false;    }    private boolean isCanPullDown() {      return !canScrollVertically(-1);    }    private boolean isCanPullUp() {      return !canScrollVertically(1);    }//    private int scrollLoad() {//      int lastItem = 0;//      int itemCount = 0;//      int spanCount = 1;//      if (staggeredGridLayoutManager != null) {//        lastItem = staggeredGridLayoutManager.findLastVisibleItemPositions(null)[0];//        itemCount = staggeredGridLayoutManager.getItemCount();//        spanCount = staggeredGridLayoutManager.getSpanCount();//      } else if (linearLayoutManager != null) {//        lastItem = linearLayoutManager.findLastVisibleItemPosition();//        itemCount = linearLayoutManager.getItemCount();//        spanCount = 1;//      } else if (gridLayoutManager != null) {//        lastItem = gridLayoutManager.findLastVisibleItemPosition();//        itemCount = gridLayoutManager.getItemCount();//        spanCount = gridLayoutManager.getSpanCount();//      }//      return ((itemCount - 1) / spanCount + 1) - (lastItem / spanCount + 1);//    }    private boolean isVertical() {      if (staggeredGridLayoutManager != null)        return staggeredGridLayoutManager.getOrientation() == StaggeredGridLayoutManager.VERTICAL;      else if (linearLayoutManager != null)        return linearLayoutManager.getOrientation() == LinearLayoutManager.VERTICAL;      else if (gridLayoutManager != null)        return gridLayoutManager.getOrientation() == GridLayoutManager.VERTICAL;      return false;    }//    public void onScrolled(int dx, int dy) {//      if (dy > 0 && !isScrollLoad) {//        if (oLior != null) {//          onScrollListener.scrollLoad(sc```````````llLoad());//傳遞滾動到倒數(shù)第幾行//        }//      }//    }  }

這樣我們變實現(xiàn)了自己的刷新加載框架,代碼我已上傳:SWPullRecyclerLayout_jb51.rar

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 凤翔县| 军事| 安顺市| 白山市| 宜昌市| 金乡县| 红河县| 汉寿县| 建阳市| 广南县| 天津市| 囊谦县| 米泉市| 施秉县| 贺州市| 开远市| 德惠市| 石嘴山市| 沿河| 定日县| 嘉义市| 罗山县| 台北市| 沂南县| 桃园市| 博客| 永昌县| 特克斯县| 桐城市| 韶山市| 盐亭县| 囊谦县| 龙川县| 平邑县| 石楼县| 怀集县| 越西县| 乐东| 大厂| 东辽县| 车致|