欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android中Listview下拉刷新和上拉加載更多的多種實(shí)現(xiàn)方案

 更新時(shí)間:2016年12月26日 08:58:50   作者:huang502  
本文大概通過三種方案給大家介紹了Android中Listview下拉刷新和上拉加載更多知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下

 listview經(jīng)常結(jié)合下來刷新和上拉加載更多使用,本文總結(jié)了三種常用到的方案分別作出說明。

     方案一:添加頭布局和腳布局

        android系統(tǒng)為listview提供了addfootview和addheadview兩個(gè)API。這樣可以直接自定義一個(gè)View,以添加視圖的形式實(shí)現(xiàn)下來刷新和上拉加載。

     實(shí)現(xiàn)步驟   

       1、創(chuàng)建一個(gè)類繼承ListView:class PullToRefreshListView extends ListView; 

     2、在構(gòu)造方法中添加HeadView:addHeaderView(headView);

       3、獲取HeadView的高。測量控件的高可以有兩方法getMeasuredHeight和getHeight,getMeasuredHeight()在onMeasure方法執(zhí)行之后才能獲取到;getHeight()  在onLayout方法執(zhí)行之后才能獲取到值;

       4、顯示和隱藏headView,通過setpadding實(shí)現(xiàn),當(dāng)向下滑,且第一條可見item是第0條的時(shí)候才需要設(shè)置HeadView的paddingTop來顯示HeadView。          

       顯示:headView.setPadding(0,0,0,0);     

       隱藏:headView.setPadding(0,-headViewHeight,0,0);

      5、下拉刷新三種狀態(tài)的判斷,移動(dòng)的時(shí)候,當(dāng)paddingTop < 0 的時(shí)候,說明HeadView沒有完全顯示出來,進(jìn)入下拉刷新狀態(tài);移動(dòng)的時(shí)候,當(dāng)paddingTop >= 0 的時(shí)候,   說明HeadView已經(jīng)完全顯示出來了,進(jìn)入松開以新狀態(tài);手指抬起的時(shí)候,且當(dāng)前狀態(tài)是松開刷新狀態(tài)的時(shí)候,進(jìn)入正在刷新狀態(tài); 當(dāng)已經(jīng)是“正在刷新”狀態(tài)時(shí),   則不允許再做”下拉刷新”和”松開刷新”的操作了,在Move事件中加入判斷,如果已經(jīng)是正在刷新狀態(tài)了,則不處理下拉的操作了。      

       6、下拉箭頭的轉(zhuǎn)動(dòng)。下拉刷新是向下,松開刷新時(shí)向上。旋轉(zhuǎn)動(dòng)畫通過屬性動(dòng)畫實(shí)現(xiàn)。隱藏箭頭的時(shí)候要清除動(dòng)畫:iv_arrow.clearAnimation();  如果不隱藏動(dòng)畫效果,設(shè)置View.GONE之后還是看得見的。    

       7、HeadView顯示時(shí),當(dāng)手指松開時(shí)的處理,松開時(shí)如果是“正在刷新”狀態(tài),則把headVie完全顯示;松開時(shí)如果是“下拉刷新”狀態(tài),則把HeadView完全隱藏    

       8、增加FooterView:addFooterView(footerView)。當(dāng)ListView處于空閑狀態(tài),并且最后一條可見item是ListView中的最后一條數(shù)據(jù)時(shí)顯示footview,   footerView顯示出來后,ListView不會(huì)自動(dòng)上滑把FooterView顯示出來的,所以需要手動(dòng)設(shè)置:setSelection(getCount() - 1);即選中最后一條。     

      9、增加回調(diào)監(jiān)聽器。當(dāng)ListView處于刷新狀態(tài)的時(shí)候會(huì)調(diào)用onRefreshing()方法;當(dāng)ListView處于加載更多的時(shí)候會(huì)調(diào)用onLoadMore()。加載完成后通知控件加載完成。

       具體實(shí)現(xiàn):

import com.itheima.pulltorefreshlistview.R;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
public class PullToRefreshListView extends ListView {
  private View headerView;
  private float downY;
  private int headerViewHeight;
  /** 狀態(tài):下拉刷新 */
  private static final int STATE_PULL_TO_REFRESH = 0;
  /** 狀態(tài):松開刷新 */
  private static final int STATE_RELEASE_REFRESH = 1;
  /** 狀態(tài):正在刷新 */
  private static final int STATE_REFRESHING = 2;
  /** 當(dāng)前狀態(tài) */
  private int currentState = STATE_PULL_TO_REFRESH;  // 默認(rèn)是下拉刷新狀態(tài)
  private ImageView iv_arrow;
  private ProgressBar progress_bar;
  private TextView tv_state;
  private RotateAnimation upAnim;
  private RotateAnimation downAnim;
  private OnRefreshingListener mOnRefreshingListener;
  private View footerView;
  private int footerViewHeight;
  /** 正在加載更多 */
  private boolean loadingMore;
  public PullToRefreshListView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initHeaderView();
    initFooterView();
  }
  private void initHeaderView() {
    headerView = View.inflate(getContext(), R.layout.header_view, null);
    iv_arrow = (ImageView) headerView.findViewById(R.id.iv_arrow);
    progress_bar = (ProgressBar) headerView.findViewById(R.id.progress_bar);
    showRefreshingProgressBar(false);
    tv_state = (TextView) headerView.findViewById(R.id.tv_state);
    headerView.measure(0, 0);  // 主動(dòng)觸發(fā)測量,mesure內(nèi)部會(huì)調(diào)用onMeasure
    headerViewHeight = headerView.getMeasuredHeight();
    hideHeaderView();
    super.addHeaderView(headerView);
    upAnim = createRotateAnim(0f, -180f);
    downAnim = createRotateAnim(-180f, -360f);
  }
  private void initFooterView() {
    footerView = View.inflate(getContext(), R.layout.footer_view, null);
    footerView.measure(0, 0);// 主動(dòng)觸發(fā)測量,mesure內(nèi)部會(huì)調(diào)用onMeasure
    footerViewHeight = footerView.getMeasuredHeight();
    hideFooterView();
    super.addFooterView(footerView);
    super.setOnScrollListener(new OnScrollListener() {
      // 當(dāng)ListView滾動(dòng)的狀態(tài)發(fā)生改變的時(shí)候會(huì)調(diào)用這個(gè)方法
      @Override
      public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (scrollState == OnScrollListener.SCROLL_STATE_IDLE  // ListView處于空閑狀態(tài)
            && getLastVisiblePosition() == getCount() - 1  // 界面上可見的最后一條item是ListView中最后的一條item
            && loadingMore == false              // 如果當(dāng)前沒有去做正在加載更多的事情
            ) {
          loadingMore = true;
          showFooterView();
          setSelection(getCount() - 1);
          if (mOnRefreshingListener != null) {
            mOnRefreshingListener.onLoadMore();
          }
        }
      }
      // 當(dāng)ListView滾動(dòng)的時(shí)候會(huì)調(diào)用這個(gè)方法
      @Override
      public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
      }
    });
  }
  private void hideFooterView() {
    int paddingTop = -footerViewHeight;
    setFooterViewPaddingTop(paddingTop);
  }
  private void showFooterView() {
    int paddingTop = 0;
    setFooterViewPaddingTop(paddingTop);
  }
  private void setFooterViewPaddingTop(int paddingTop) {
    footerView.setPadding(0, paddingTop, 0, 0);
  }
  /**
   * 設(shè)置顯示進(jìn)度的圈圈
   * @param showProgressBar 如果是true,則顯示ProgressBar,否則的話顯示箭頭
   */
  private void showRefreshingProgressBar(boolean showProgressBar) {
    progress_bar.setVisibility(showProgressBar ? View.VISIBLE : View.GONE);
    iv_arrow.setVisibility(!showProgressBar ? View.VISIBLE : View.GONE);
    if (showProgressBar) {
      iv_arrow.clearAnimation();  // 有動(dòng)畫的View要清除動(dòng)畫才能真正的隱藏
    }
  }
  /**
   * 創(chuàng)建旋轉(zhuǎn)動(dòng)畫
   * @param fromDegrees 從哪個(gè)角度開始轉(zhuǎn)
   * @param toDegrees 轉(zhuǎn)到哪個(gè)角度
   * @return 
   */
  private RotateAnimation createRotateAnim(float fromDegrees, float toDegrees) {
    int pivotXType = RotateAnimation.RELATIVE_TO_SELF;    // 旋轉(zhuǎn)點(diǎn)的參照物
    int pivotYType = RotateAnimation.RELATIVE_TO_SELF;    // 旋轉(zhuǎn)點(diǎn)的參照物
    float pivotXValue = 0.5f;  // 旋轉(zhuǎn)點(diǎn)x方向的位置
    float pivotYValue = 0.5f;  // 旋轉(zhuǎn)點(diǎn)y方向的位置
    RotateAnimation ra = new RotateAnimation(fromDegrees, toDegrees, pivotXType, pivotXValue, pivotYType, pivotYValue);
    ra.setDuration(300);
    ra.setFillAfter(true);  // 讓動(dòng)畫停留在結(jié)束位置
    return ra;
  }
  /** 隱藏HeaderView */
  private void hideHeaderView() {
    int paddingTop = -headerViewHeight;
    setHeaderViewPaddingTop(paddingTop);
  }
  /** 顯示HeaderView */
  private void showHeaderView() {
    int paddingTop = 0;
    setHeaderViewPaddingTop(paddingTop);
  }
  /**
   * 設(shè)置HeaderView的paddingTop
   * @param paddingTop
   */
  private void setHeaderViewPaddingTop(int paddingTop) {
    headerView.setPadding(0, paddingTop, 0, 0);
  }
  @Override
  public boolean onTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
    case MotionEvent.ACTION_DOWN:
      downY = ev.getY();
      break;
    case MotionEvent.ACTION_MOVE:
      if (currentState == STATE_REFRESHING) {
        // 如果當(dāng)前已經(jīng)是“正在刷新“的狀態(tài)了,則不用去處理下拉刷新了
        return super.onTouchEvent(ev);
      }
      int fingerMoveDistanceY = (int) (ev.getY() - downY);    // 手指移動(dòng)的距離
      // 如果是向下滑動(dòng),并且界面上可見的第一條item是ListView的索引為0的item時(shí)我們才處理下拉刷新的操作
      if (fingerMoveDistanceY > 0 && getFirstVisiblePosition() == 0) {
        int paddingTop = -headerViewHeight + fingerMoveDistanceY;
        setHeaderViewPaddingTop(paddingTop);
        if (paddingTop < 0 && currentState != STATE_PULL_TO_REFRESH) {
          // 如果paddingTop小于0,說明HeaderView沒有完全顯示出來,則進(jìn)入下拉刷新的狀態(tài)
          currentState = STATE_PULL_TO_REFRESH;
          tv_state.setText("下拉刷新");
          iv_arrow.startAnimation(downAnim);
          showRefreshingProgressBar(false);
          // 讓箭頭轉(zhuǎn)一下
        } else if (paddingTop >= 0 && currentState != STATE_RELEASE_REFRESH) {
          // 如果paddingTop>=0,說明HeaderView已經(jīng)完全顯示出來,則進(jìn)入松開刷新的狀態(tài)
          currentState = STATE_RELEASE_REFRESH;
          tv_state.setText("松開刷新");
          iv_arrow.startAnimation(upAnim);
          showRefreshingProgressBar(false);
        }
        return true;
      }
      break;
    case MotionEvent.ACTION_UP:
      if (currentState == STATE_RELEASE_REFRESH) {
        // 如果當(dāng)前狀態(tài)是松開刷新,并且抬起了手,則進(jìn)入正在刷新狀態(tài)
        currentState = STATE_REFRESHING;
        tv_state.setText("正在刷新");
        showRefreshingProgressBar(true);
        showHeaderView();
        if (mOnRefreshingListener != null) {
          mOnRefreshingListener.onRefreshing();
        }
      } else if (currentState == STATE_PULL_TO_REFRESH) {
        // 如果抬起手時(shí)是下拉刷新狀態(tài),則把HeaderView完成隱藏
        hideHeaderView();
      }
      break;
    }
    return super.onTouchEvent(ev);
  }
  public void setOnRefreshingListener(OnRefreshingListener mOnRefreshingListener) {
    this.mOnRefreshingListener = mOnRefreshingListener;
  }
  /** ListView刷新的監(jiān)聽器 */
  public interface OnRefreshingListener {
    /** 當(dāng)ListView可以刷新數(shù)據(jù)的時(shí)候會(huì)調(diào)用這個(gè)方法 */
    void onRefreshing();
    /** 當(dāng)ListView可以加載更多 的時(shí)候會(huì)調(diào)用這個(gè)方法 */
    void onLoadMore();
  }
  /** 聯(lián)網(wǎng)刷新數(shù)據(jù)的操作已經(jīng)完成了 */
  public void onRefreshComplete() {
    hideHeaderView();
    currentState = STATE_PULL_TO_REFRESH;
    showRefreshingProgressBar(false);
  }
  /** 加載更多新數(shù)據(jù)的操作已經(jīng)完成了 */
  public void onLoadmoreComplete() {
    hideFooterView();
    loadingMore = false;
  }
}

 方案二: listview的多種樣式顯示

        設(shè)置listview的適配器的時(shí)候可以實(shí)現(xiàn)兩個(gè)方法: getViewTypeCount()和getItemViewType(),前者指定條目的種類,后者返回具體的類型,這樣可以根據(jù)不同的類型設(shè)計(jì)相關(guān)的樣式,包括上拉加載更多,和下拉刷新,兩者類似,因此這里僅僅給出加載更多的寫法。具體實(shí)現(xiàn)如下:

        1、重寫getViewTypeCount()和getItemViewType(),這里包括普通的item條目和加載更多的條目,所以getViewTypeCount()返回值為2;

@Override
  public int getViewTypeCount() {
    return super.getViewTypeCount() + 1;
  }
  @Override
  public int getItemViewType(int position) {
    if (position == getCount() - 1) {
      return 0;
    } else {
      return addViewType(position); //構(gòu)造一個(gè)方法出來,方便子類修改,添加更多的樣式
    }
  }
  public int addViewType(int position) {
    return 1;
  }

         2、在getview()中針對(duì)不同的類型添加布局:

 @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    BaseHoldle holdle;
    if (convertView == null) {
      if (getItemViewType(position) == 0) { //type為0 表示應(yīng)該加載加載更多的視圖
        holdle = getLoadmoreHoldle();
      } else {                //否則為普通視圖
        holdle = getSpecialBaseHoldle(position);
      }
    } else {
      holdle = (BaseHoldle) convertView.getTag();
    }
    if (getItemViewType(position) == 0) {   //加載更多視圖,請(qǐng)求網(wǎng)絡(luò)獲取數(shù)據(jù)
      if (havemore()) {
        holdle.setDataAndRefreshHoldleView(LoadmoreHoldle.LOADMORE_LODING);
        triggleLoadMoreData();
      } else {               
        holdle.setDataAndRefreshHoldleView(LoadmoreHoldle.LOADMORE_NONE);
      }
    } else {                 //普通視圖視圖,請(qǐng)求網(wǎng)絡(luò)獲取數(shù)據(jù)
      T data = (T) mdata.get(position);
      holdle.setDataAndRefreshHoldleView(data);
    }
    mHoldleView = holdle.mHoldleView;
    mHoldleView.setScaleX(0.6f);
    mHoldleView.setScaleY(0.6f);
    ViewCompat.animate(mHoldleView).scaleX(1).scaleY(1).setDuration(400).setInterpolator(new OvershootInterpolator(4)).start();
    return mHoldleView;
  }

           3、具體的加載更多視圖的實(shí)現(xiàn)

private BaseHoldle getLoadmoreHoldle() {
    if (mLoadmoreHoldle == null) {
      mLoadmoreHoldle = new LoadmoreHoldle();
    }
    return mLoadmoreHoldle;
  }
  public class LoadmoreHoldle extends BaseHoldle {
  @Bind(R.id.item_loadmore_container_loading)
  LinearLayout itemloadmorecontainerloading;
  @Bind(R.id.item_loadmore_container_retry)
  LinearLayout itemloadmorecontainerretry;
  @Bind(R.id.item_loadmore_tv_retry)
  TextView item_loadmore_tv_retry;
  public static final int LOADMORE_LODING = 0;
  public static final int LOADMORE_ERROR = 1;
  public static final int LOADMORE_NONE = 2;
  private int mCurretState;
  @Override
  public void refreshHoldleView(Object data) {
    itemloadmorecontainerloading.setVisibility(View.GONE);
    itemloadmorecontainerretry.setVisibility(View.GONE);
    mCurretState = (int) data;
    switch (mCurretState) {
      case LOADMORE_LODING:
        itemloadmorecontainerloading.setVisibility(View.VISIBLE);
        break;
      case LOADMORE_ERROR:
        itemloadmorecontainerretry.setVisibility(View.VISIBLE);
        break;
      case LOADMORE_NONE:
        break;
    }
  }
  @Override
  public View ininViewHoldle() {
    View view = View.inflate(UiUtils.getContext(), R.layout.itemloadmore, null);
    ButterKnife.bind(this, view);
    return view;
  }
}
//holder基類,提取公共的方法
public abstract class BaseHoldle<T> {
  public View mHoldleView;
  public T mdata;
  public BaseHoldle() {
    mHoldleView = ininViewHoldle();
    mHoldleView.setTag(this);
  }
  public void setDataAndRefreshHoldleView(T mdata) {
    this.mdata = mdata;
    refreshHoldleView(mdata);
  }
  public abstract void refreshHoldleView(T data);
  public abstract View ininViewHoldle();
}

方案三: SwipeRefreshLayout實(shí)現(xiàn)下來刷新

     SwipeRefreshLayout對(duì)下不兼容,且只有下拉刷新功能沒有上拉加載更多的功能。當(dāng)時(shí)作為Andriod5.0之后的新特性,使用起來方便,可以直接調(diào)用系統(tǒng)的API。使用方法也較為簡單。具體實(shí)現(xiàn)如下:

    首先聲明控件,設(shè)置顏色: 

 refreshLayout = (SwipeRefreshLayout) findViewById(R.id.refresh);
   refreshLayout.setOnRefreshListener(this); 
   refreshLayout.setColorSchemeResources(android.R.color.holo_blue_bright,
      android.R.color.holo_green_light,android.R.color.holo_orange_light,
      android.R.color.holo_red_light);
   refreshLayout.setProgressBackgroundColor(R.color.refresh_bg);
   refreshLayout.setProgressBackgroundColor(R.color.refresh_bg);

    寫一個(gè)類實(shí)現(xiàn)SwipeRefreshLayout.OnRefreshListener,重寫onRefresh()方法:

@Override  
  public void onRefresh() { 
   refreshLayout.postDelayed(new Runnable() {
    @Override
    public void run() {
     //請(qǐng)求網(wǎng)絡(luò),獲取數(shù)據(jù)        
     refreshLayout.setRefreshing(false);
    }
    },3000);
  }

以上所述是小編給大家介紹的Android中Listview下拉刷新和上拉加載更多的多種實(shí)現(xiàn)方案,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

最新評(píng)論