Android 新控件之SwipeRefreshLayout添加上拉加載和下拉刷新

寫著篇博客開始 ,不得不得發(fā)發(fā)牢騷了。為什么你搞一個下拉刷新,你為什么不直接再加一個上拉加載呢? 我們都很藍(lán)瘦啊,開心的用上了原生的swiperefreshlayout 但是萬萬沒想到 人家只有下拉刷新 沒有上拉加載。
  他沒有加怎么辦? 我們自己加啊。那么牛逼已經(jīng)吹出去了 ,接下來就是教大家如何添加上拉加載。下拉刷新的話其實(shí)很簡單我就簡單貼上代碼


setColorSchemeResources(R.color.orange, R.color.green,
R.color.holo_red_light); // 進(jìn)度動畫顏色
setProgressBackgroundColorSchemeResource(
R.color.light_gray); // 進(jìn)度背景顏色

就加上上面的配置下顏色就行。那么如何添加上拉加載呢
  首先 大家要明白什么時(shí)候出現(xiàn)上拉加載 就是listview 滾動到底部的時(shí)候添加上拉加載。如何判斷到了底部呢。網(wǎng)上你查的很多都是這樣的?

lv.getLastVisiblePosition()==lv.getAdapter().getCount()-1

那么這樣到底行不行? 答案是行 但是有些不盡人意 因?yàn)槿绻愕臈l目夠高的話你會發(fā)現(xiàn),最后一個條目剛露頭 你就開始加載了 ,但是用戶完全懵逼不知道到底了。所以如何在真正的滾到底部的時(shí)候加載呢。就是加一個判斷最后一個條目的bottom 如果等于 listview 的高度那么肯定是滾動到底部了吧所以最后判斷是這樣的

if(lv.getLastVisiblePosition()==lv.getAdapter().getCount()-1 //最后一個條目
     &&!isLoading // 之前沒有執(zhí)行加載 防止重新加載
     &&isPullUp()  // 是上拉操作 根據(jù)touchevent判斷y 坐標(biāo)即可){
ViewlastVisibleItemView=lv.getChildAt(lv.getChildCount() - 1);
    if (lastVisibleItemView != null && lastVisibleItemView.getBottom() == lv.getHeight()) {
      // 執(zhí)行上拉加載更多
  }
}

這樣 上拉加載的觸發(fā)條件我們就知道了。那么接下來就是 在觸發(fā)的時(shí)候?yàn)閘istview 添加一個footer 就行了。 然后在加載完畢移除這個footer 就完事了 ,那這么說是不是很簡單的完成了呢 我想說基本的上拉加載你知道這些就可以完成了。那么很多上拉加載的都是一邊網(wǎng)上拉一邊改變底部加載的高度是怎么實(shí)現(xiàn)的呢? 我簡單說下原理因?yàn)槲蚁勇闊]做 (鄙視自己一秒鐘)其實(shí)就是先添加那個footer 然后設(shè)置他的margintop 為一個負(fù)值 這樣他可以隱藏起來, 當(dāng)我們滾動到底部的時(shí)候 監(jiān)聽手機(jī)移動事件根據(jù)那個y變化 ,動態(tài)改變footer 的margin,最后當(dāng)footer 完全顯示時(shí) 執(zhí)行加載動畫?!∥抑苯淤N上最后的代碼

* Created by sunyeyu  on 2017-02-28 .
*/
public class MySwipeRefreshLayout extends SwipeRefreshLayout implements AbsListView.OnScrollListener {
  private ListView lv;
  int footerLayoutId;
  private boolean isLoading;
  private float downY;
  private float upY;
  private View footer;
  private boolean isRefreshFoot;
public MySwipeRefreshLayout(Context context) {
 super(context);
 init();
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 intchilds=getChildCount();
  if (childs>0) {
   if (getChildAt(1)instanceof ListView) {
   if(lv==null) { // 要判斷為空時(shí)才進(jìn)行下面的操作 因?yàn)槊看萎?dāng)下拉刷新的時(shí)候 omeasure 是會多次調(diào)用的 所以避免重復(fù)調(diào)用
   lv= (ListView) getChildAt(1);// 這里我們是用的1 因?yàn)? 是那個下拉刷新的源圈
   lv.setAdapter(ba);
   lv.setOnScrollListener(this);
   lv.setOnItemClickListener(oic);
   footer=View.inflate(getContext(),footerLayoutId,null);
}
}
}
}
public MySwipeRefreshLayout(Context context, AttributeSet attrs) {
  super(context, attrs);
  TypedArrayta=context.obtainStyledAttributes(attrs, R.styleable.MySwipeRefreshLa  yout);// 我這里用了自定義屬性來添加footer 的布局
   footerLayoutId=ta.getResourceId(R.styleable.MySwipeRefreshLayout_footerLayoutI   d,0); // 得到footer布局id 加載出view
   if(footerLayoutId==0){
   Log.e("MySwipeRefreshLayout","沒有在xml配置footer的布局id屬性");
}
init();
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
  switch (ev.getAction()){
    case MotionEvent.ACTION_DOWN:
     downY=ev.getRawY();
     break;
    case MotionEvent.ACTION_UP:
     upY=ev.getRawY();
     canLoadMore();// 抬起是判斷是否可以顯示上拉加載
  }
   return super.dispatchTouchEvent(ev);
}
 AdapterView.OnItemClickListener oic;
 public void setListItemClickListener(AdapterView.OnItemClickListener oic){
    this.oic=oic; // 我這里并沒有直接用 lv.setonitemclicklistener(oic)  因?yàn)檫@   時(shí)候 lv 還沒有被賦值 這時(shí)候調(diào)用時(shí)會報(bào)空指針的。
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
   return super.onInterceptTouchEvent(ev);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
  @Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
  int totalItemCount) {
   canLoadMore();
}
private void canLoadMore() {
   if(lv.getLastVisiblePosition()==lv.getAdapter().getCount()-1&&
    !isLoading&&isPullUp()){
    ViewlastVisibleItemView=lv.getChildAt(lv.getChildCount() - 1);
   if (lastVisibleItemView != null && lastVisibleItemView.getBottom() == lv.getHeight())    {
   Load();
    }
   }
}
private boolean isPullUp() {
   if(upY
    return true;
   }
    return  false;
}
private void Load(){
   isLoading=true;
    lv.addFooterView(footer);
   if(mOnLoadListener!=null){
    mOnLoadListener.onLoad();
   }
}
public void setFooter(boolean hasRefreshFoot){
  if(!hasRefreshFoot){
    lv.removeFooterView(footer);
    isLoading=false;
  }
}
public void setHeaderListener(OnRefreshListener ol){
   setColorSchemeResources(R.color.orange, R.color.green,
   R.color.holo_red_light); // 進(jìn)度動畫顏色
   setProgressBackgroundColorSchemeResource(
   R.color.light_gray); // 進(jìn)度背景顏色
   setOnRefreshListener(ol);
}
BaseAdapter ba;
public void setAdapter(BaseAdapter ba){
   this.ba=ba;
}
/**  刷新結(jié)束 取消下拉刷新 */
public void setHeader(boolean isHeader){
   setRefreshing(isHeader);
}
    /**
      * 加載更多的監(jiān)聽器
    */
public interface OnLoadMoreListener {
   void onLoad();
}
OnLoadMoreListener mOnLoadListener;
public void setOnLoadListener(OnLoadMoreListener loadListener) {
   mOnLoadListener=loadListener;
  }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容