一個(gè)簡(jiǎn)單的上拉加載更多的ListView

最近項(xiàng)目中由于統(tǒng)一使用SwipeRefreshLayout的下拉刷新,由于谷歌官方的SwipeRefreshLayout并沒(méi)有提供上拉加載更多的功能需频,只好自己寫(xiě)一個(gè)暗甥,記一下以后可以直接拿出來(lái)用。
  其實(shí)實(shí)現(xiàn)原理很中規(guī)中矩皂甘,無(wú)非就是給ListView添加一個(gè)腳布局(用于顯示正在加載更多的提示)斧散,首先是隱藏的(設(shè)置一個(gè)負(fù)值padding供常,剛好為腳布局高度的相反數(shù)),當(dāng)監(jiān)聽(tīng)到用戶(hù)滑倒最底端(當(dāng)前可見(jiàn)的最后一個(gè)item是當(dāng)前列表的最后一項(xiàng)再繼續(xù)上拉的動(dòng)作時(shí)顯示腳布局鸡捐,加載完成后再隱藏它栈暇,這里為了避免加載多次,我們需要記錄用戶(hù)上拉時(shí)是否正在加載箍镜,只有當(dāng)同時(shí)滿(mǎn)足:①?zèng)]有正在加載源祈;②當(dāng)前已經(jīng)到了最低端;③用戶(hù)正在上拉操作時(shí)才加載更多色迂。
  這里我覺(jué)得重寫(xiě)onTouchEvent判斷用戶(hù)上拉還是下拉比較麻煩香缺,就直接監(jiān)聽(tīng)滑動(dòng)狀態(tài),如果當(dāng)前最后一個(gè)可見(jiàn)的item是列表最后一項(xiàng),當(dāng)滑動(dòng)狀態(tài)處于SCROLL_STATE_FLING(開(kāi)始滾動(dòng))或者SCROLL_STATE_IDLE(處于空閑歇僧,已經(jīng)停止)時(shí)图张,如果滑動(dòng)狀態(tài)再發(fā)生改變只能是變?yōu)镾CROLL_STATE_TOUCH_SCROLL(滾動(dòng)狀態(tài))锋拖,由于最后一個(gè)可見(jiàn)的item必須是最后一個(gè),所以綜上可知只能變?yōu)橄蛏侠?向下拉最后一個(gè)可見(jiàn)的就不是列表的最后一項(xiàng)了)祸轮,下面是實(shí)現(xiàn)的代碼

package com.meskal.customview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListView;
import com.meskal.R;


public class PullUpLoadMoreListView extends ListView implements AbsListView.OnScrollListener {

  private boolean isLoading  = false;

  private View mFooterView;

  private int mFooterHeight;

  private OnLoadMoreListener mListener;
  private LayoutInflater inflater;

  public PullUpLoadMoreListView(Context context) {
    this(context, null);
  }

  public PullUpLoadMoreListView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public PullUpLoadMoreListView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    initFooterView();
    setOnScrollListener(this);
  }

  /**
   * 初始化腳布局
   */
  private void initFooterView() {
    mFooterView = inflater.inflate(R.layout.refresh_load_more, null);
    mFooterView.measure(0, 0);
    mFooterHeight = mFooterView.getMeasuredHeight();
    mFooterView.setPadding(0, -mFooterHeight, 0, 0);
    this.addFooterView(mFooterView);
  }

  @Override public void onScrollStateChanged(AbsListView absListView, int scrollstate) {
    if(this.getLastVisiblePosition() == this.getAdapter().getCount() - 1
        && !isLoading && (scrollstate == SCROLL_STATE_FLING || scrollstate == SCROLL_STATE_IDLE)){
      setLoadState(true);
      if(this.mListener != null){
        this.mListener.loadMore();
      }
    }
  }

  /**
   * 設(shè)置狀態(tài)
   * @param b
   */
  public void setLoadState(boolean b) {
    this.isLoading = b;
    if(isLoading){
      mFooterView.setPadding(0,0,0,0);
      this.setSelection(this.getAdapter().getCount() + 1);
    }else {
      mFooterView.setPadding(0,-mFooterHeight,0,0);
    }
  }

  @Override public void onScroll(AbsListView absListView, int i, int i1, int i2) {

  }

  public void setOnLoadMoreListener(OnLoadMoreListener listener){
    this.mListener = listener;
  }

  public interface OnLoadMoreListener{
    void loadMore();
  }
}

腳布局就很簡(jiǎn)單了兽埃,當(dāng)然也可以更具需要定制更絢麗的進(jìn)度提醒:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/block_bg"
    android:orientation="horizontal">

  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="50dp"
      android:orientation="horizontal"
      android:gravity="center"
      >
    <ProgressBar
        android:id="@+id/progressBar"
        style="@android:style/Widget.Holo.ProgressBar.Small"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="5dp"
        />


    <TextView
        android:layout_width="wrap_content"
        android:layout_marginLeft="5dp"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="18sp"
        android:textColor="#FF333333"
        android:text="正在加載更多數(shù)據(jù)..."
        />

  </LinearLayout>
</LinearLayout>

這里腳布局加了一個(gè)邊框(drawable下添加一個(gè)block_bg.xml):

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
  <solid android:color="#fff"/>

  <stroke
      android:color="#d4d4d4"
      android:width="1px"/>

</shape>

對(duì)外我們對(duì)外公開(kāi)一個(gè)設(shè)置監(jiān)聽(tīng)器和設(shè)置加載狀態(tài)的方法,監(jiān)聽(tīng)器接口在使用時(shí)實(shí)現(xiàn)這個(gè)接口去做加載更多的操作适袜,設(shè)置正在加載中由控件本身負(fù)責(zé)柄错,這個(gè)時(shí)候我們讓腳布局顯示出來(lái),加載完成我們?cè)O(shè)置正在加載中(isLoading )為false就會(huì)隱藏腳布局苦酱,這里對(duì)于腳布局我們需要注意的時(shí)獲取高度之前要先主動(dòng)的去測(cè)量一下( mFooterView.measure(0, 0);)售貌,因?yàn)樵趘iew繪制中只有當(dāng)view執(zhí)行過(guò)onMeasure后才能得到具體寬高,否則得到的始終為0疫萤。
  到這里颂跨,這個(gè)控件差不多寫(xiě)完了,其實(shí)配合SwipeRefreshLayout效果還不錯(cuò)给僵。當(dāng)然下拉刷新上拉加載的類(lèi)庫(kù)也有很多毫捣,像有名的PullToRefresh详拙,功能十分強(qiáng)大帝际,使用也很方便。還有記得之前使用過(guò)一個(gè)MaterialRefreshLayout饶辙,這個(gè)是比SwipeRefreshLayout更強(qiáng)大的刷新控件蹲诀,支持上拉加載更多,上拉和下拉顯示的都是轉(zhuǎn)圈的動(dòng)畫(huà)弃揽,上拉在底部顯示脯爪,而且支持動(dòng)畫(huà)顯示是否是侵入式的覆蓋在內(nèi)容上方

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市矿微,隨后出現(xiàn)的幾起案子痕慢,更是在濱河造成了極大的恐慌,老刑警劉巖涌矢,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掖举,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡娜庇,警方通過(guò)查閱死者的電腦和手機(jī)塔次,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)名秀,“玉大人励负,你說(shuō)我怎么就攤上這事∝暗茫” “怎么了继榆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我略吨,道長(zhǎng)攒发,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任晋南,我火速辦了婚禮惠猿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘负间。我一直安慰自己偶妖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布政溃。 她就那樣靜靜地躺著趾访,像睡著了一般。 火紅的嫁衣襯著肌膚如雪董虱。 梳的紋絲不亂的頭發(fā)上扼鞋,一...
    開(kāi)封第一講書(shū)人閱讀 52,196評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音愤诱,去河邊找鬼云头。 笑死,一個(gè)胖子當(dāng)著我的面吹牛淫半,可吹牛的內(nèi)容都是我干的溃槐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼科吭,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼昏滴!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起对人,我...
    開(kāi)封第一講書(shū)人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤谣殊,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后牺弄,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體姻几,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年猖闪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鲜棠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡培慌,死狀恐怖豁陆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吵护,我是刑警寧澤盒音,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布表鳍,位于F島的核電站,受9級(jí)特大地震影響祥诽,放射性物質(zhì)發(fā)生泄漏譬圣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一雄坪、第九天 我趴在偏房一處隱蔽的房頂上張望厘熟。 院中可真熱鬧,春花似錦维哈、人聲如沸绳姨。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)飘庄。三九已至,卻和暖如春购撼,著一層夾襖步出監(jiān)牢的瞬間跪削,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工迂求, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留碾盐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓锁摔,卻偏偏與公主長(zhǎng)得像廓旬,于是被迫代替她去往敵國(guó)和親哼审。 傳聞我的和親對(duì)象是個(gè)殘疾皇子谐腰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容