Android 응용 프로그램 에서 ListView 는 OnScrollListener 를 이용 하여 페이지 별로 데 이 터 를 불 러 옵 니 다.

11359 단어 AndroidListView
사용자 가 인터넷 에서 얇 은 것 을 읽 을 때 사용자 가 읽 지 않 은 얇 은 것 을 한꺼번에 불 러 오 면 비교적 긴 시간 이 걸 리 고 좋 지 않 은 사용자 체험 을 하 게 되 며 한 화면의 내용 도 이렇게 많은 내용 을 표시 하기 에는 부족 하 다.이때 우 리 는 또 다른 기능 을 사용 해 야 한다.그것 이 바로 listview 의 페이지 이다.페이지 를 나 누 어 데 이 터 를 불 러 오 면 사용자 가 보 는 만큼 불 러 옵 니 다.
보통 이것 도 두 가지 방식 으로 나 뉘 는데 하 나 는 단 추 를 설정 하고 사용자 가 클릭 하면 불 러 옵 니 다.다른 하 나 는 사용자 가 끝까지 미 끄 러 질 때 자동 으로 불 러 오 는 것 입 니 다.오늘 은 이 기능 의 실현 을 여러분 과 공유 하 겠 습 니 다.
우선,xml 파일 을 작성 합 니 다.moredata.xml.이 파일 은 listview 아래쪽 에 있 는 보 기 를 정의 합 니 다.

<?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="match_parent"
  android:orientation="vertical" >
 <Button  
   android:id="@+id/bt_load"  
   android:layout_width="fill_parent"  
   android:layout_height="wrap_content" 
   android:text="      " /> 
 <ProgressBar
   android:id="@+id/pg"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_gravity="center_horizontal"
   android:visibility="gone"
   />
</LinearLayout>
버튼 하나 와 진도 표시 줄 을 볼 수 있 습 니 다.하나의 프 리 젠 테 이 션 만 하기 때문에 여 기 는 간단하게 처리 합 니 다.컨트롤 의 visibility 를 설정 하여 불 러 오지 않 았 을 때 단 추 를 표시 하고 불 러 올 때 진행 바 를 표시 합 니 다.
item.xml 를 쓰 면 잘 아 실 겁 니 다.listview 의 모든 item 보 기 를 정의 합 니 다.

<?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="match_parent"
  android:orientation="vertical" >
  
  <TextView
    android:id="@+id/tv_title"
    android:textSize="20sp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="5dp"
    />
  <TextView
    android:textSize="12sp"
    android:id="@+id/tv_content"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="5dp"
    />

</LinearLayout>

main.xml 는 붙 이지 않 습 니 다.전체 메 인 화면 에 listview 가 있 습 니 다.
Activity 코드 를 직접 보고 페이지 효 과 를 실현 합 니 다.

package com.notice.moredate;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.SimpleAdapter;
import android.widget.Toast;

public class MoreDateListActivity extends Activity implements OnScrollListener {
  
  // ListView Adapter
  private SimpleAdapter mSimpleAdapter;
  private ListView lv;
  private Button bt;
  private ProgressBar pg;
  private ArrayList<HashMap<String,String>> list;
  // ListView  View
  private View moreView;
  private Handler handler;
  //            ,       
  private int MaxDateNum;
  //          
  private int lastVisibleIndex;
  
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    
    
    MaxDateNum = 22; //         

    lv = (ListView) findViewById(R.id.lv);

    //        
    moreView = getLayoutInflater().inflate(R.layout.moredate, null);

    bt = (Button) moreView.findViewById(R.id.bt_load);
    pg = (ProgressBar) moreView.findViewById(R.id.pg);
    handler = new Handler();

    //  map     ,   10   
    list = new ArrayList<HashMap<String,String>>();
    for (int i = 0; i < 10; i++) {
      HashMap<String, String> map = new HashMap<String, String>();
      map.put("ItemTitle", " " + i + "   ");
      map.put("ItemText", " " + i + "   ");
      list.add(map);
    }
    //    SimpleAdapter
    mSimpleAdapter = new SimpleAdapter(this, list, R.layout.item,
        new String[] { "ItemTitle", "ItemText" },
        new int[] { R.id.tv_title, R.id.tv_content });
    //     View,     setAdapter   
    lv.addFooterView(moreView);
    lv.setAdapter(mSimpleAdapter);
    //      
    lv.setOnScrollListener(this);

    bt.setOnClickListener(new OnClickListener() {

      @Override
      public void onClick(View v) {
        pg.setVisibility(View.VISIBLE);//       
        bt.setVisibility(View.GONE);//      

        handler.postDelayed(new Runnable() {

          @Override
          public void run() {
            loadMoreDate();//       
            bt.setVisibility(View.VISIBLE);
            pg.setVisibility(View.GONE);
            mSimpleAdapter.notifyDataSetChanged();//   listView    
          }

        }, 2000);
      }
    });

  }

  private void loadMoreDate() {
    int count = mSimpleAdapter.getCount();
    if (count + 5 < MaxDateNum) {
      //     5 
      for (int i = count; i < count + 5; i++) {
        HashMap<String, String> map = new HashMap<String, String>();
        map.put("ItemTitle", "   " + i + "   ");
        map.put("ItemText", "   " + i + "   ");
        list.add(map);
      }
    } else {
      //       5 
      for (int i = count; i < MaxDateNum; i++) {
        HashMap<String, String> map = new HashMap<String, String>();
        map.put("ItemTitle", "   " + i + "   ");
        map.put("ItemText", "   " + i + "   ");
        list.add(map);
      }
    }

  }

  @Override
  public void onScroll(AbsListView view, int firstVisibleItem,
      int visibleItemCount, int totalItemCount) {
    //            
    lastVisibleIndex = firstVisibleItem + visibleItemCount - 1;

    //               ,      View
    if (totalItemCount == MaxDateNum + 1) {
      lv.removeFooterView(moreView);
      Toast.makeText(this, "        ,      !", Toast.LENGTH_LONG).show();
    }

  }

  @Override
  public void onScrollStateChanged(AbsListView view, int scrollState) {
    //          ,  listview                 adapter   
    if (scrollState == OnScrollListener.SCROLL_STATE_IDLE
        && lastVisibleIndex == mSimpleAdapter.getCount()) {
      //           
      // pg.setVisibility(View.VISIBLE);
      // bt.setVisibility(View.GONE);
      // handler.postDelayed(new Runnable() {
      //
      // @Override
      // public void run() {
      // loadMoreDate();
      // bt.setVisibility(View.VISIBLE);
      // pg.setVisibility(View.GONE);
      // mSimpleAdapter.notifyDataSetChanged();
      // }
      //
      // }, 2000);

    }

  }
  
}

주석 을 통 해 모두 쉽게 이해 할 수 있 을 것 이다.여기 서 간단 한 해석 을 하 겠 습 니 다.우선 주의해 야 할 것 은 addFootView 방법 은 반드시 setAdapter 방법 전에 해 야 합 니 다.그렇지 않 으 면 유효 하지 않 습 니 다.addFootView 방법 은 listview 아래쪽 에 보 기 를 추가 합 니 다.이 예 에서 Button 에 progressbar 를 추가 한 보기 입 니 다.사용자 가 단 추 를 눌 렀 을 때 loadmoreDate 방법 을 호출 하여 listview 에 더 많은 데 이 터 를 연결 합 니 다.adapter 의 notifyDataSetChanged 방법 으로 listview 에 새로 고침 을 알 리 고 방금 가입 한 데 이 터 를 표시 합 니 다.
여기 서 handler 비동기 로 2 초 지연 작업 을 하여 로드 과정 을 모방 합 니 다.동시에 listview 는 onScroll Listener 모니터 를 연결 하고 onScroll 과 onScroll State Changed 방법 을 실현 합 니 다.후자 의 방법 에서 우 리 는 listview 가 스크롤 을 멈 추 었 고 마지막 으로 볼 수 있 는 항목 이 adapter 의 항목 과 같다 고 판단 함으로써 사용자 가 끝까지 미 끄 러 졌 고 자동 으로 불 러 왔 음 을 알 수 있 습 니 다.코드 는 이 부분 코드 를 주석 해 버 렸 습 니 다.여러분 이 직접 시도 해 보 세 요.
코드 에 최대 데이터 수 를 기록 하기 위해 MaxDateNum 변 수 를 추가 했다.인터넷 이나 다른 곳 에서 공 통 된 데이터 라 는 뜻 이다.onScroll 방법 을 통 해 사용자 가 이 데 이 터 를 불 러 온 것 을 판단 한 후 listview 아래쪽 보 기 를 제거 하고 더 이상 불 러 오지 못 하 게 합 니 다.또한 loadmore Date 방법 에서 도 최대 데 이 터 량 에 대해 해당 하 는 조작 을 하여 로드 수량 을 판단 합 니 다.(기본적으로 5 개 를 불 러 옵 니 다.5 개 미 만 일 때 남 은 것 을 불 러 옵 니 다).
효과 도 보기:
2016322143446104.png (480×800) 2016322143519983.png (480×800) 2016322143533203.png (480×800) 2016322143551742.png (480×800)
OnScrollListener 이벤트 순서 횟수 에 대한 간략 한 분석
Android 의 OnScroll Listener 전체 사건 에서 나 는 주로 그의 실행 순 서 를 분석 했다.
스크롤 이벤트 감청 인터페이스 구현

new AbsListView.OnScrollListener(){ 
  @Override 
  public void onScrollStateChanged(AbsListView absListView, int scrollState) 
  { 
    switch (scrollState) { 
      case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: 
        //           ,           : 2 
        break; 
      case AbsListView.OnScrollListener.SCROLL_STATE_FLING: 
        //       ,               : 4 
        break; 
      case AbsListView.OnScrollListener.SCROLL_STATE_IDLE: 
        //         ,             : 6 
        break; 
      default: 
        break; 
    } 
  } 
 
  @Override 
  public void onScroll(AbsListView absListView, int i, int i1, int i2) 
  { 
    //       ,                   : 1、3、5 
  } 
} 

그동안 혼 란 스 러 웠 는데,나중에 자세히 테스트 한 후에 위의 코드 주석 중의 결론 을 얻 었 다.
또한 ListView 그림 목록 의 스크롤 은 SCROLLSTATE_FLING 시 그림 을 표시 하지 않 고 스크롤 성능 을 향상 시 켜 스크롤 을 부 드 럽 게 합 니 다.SCROLLSTATE_IDLE 는 현재 화면 에 보 이 는 그림 을 표시 합 니 다.onScroll()인터페이스 방법 은 기본적으로 사용 하지 않 습 니 다.
보충:
1.손가락 이 화면 에 가볍게 닿 을 때 한 번 만 onScroll 방법 을 터치 하고 다른 스크롤 이벤트 가 발생 하지 않 습 니 다.
2.손가락 이 화면 에 닿 았 다가 멈 췄 다가 미 끄 러 지면 먼저 onScroll 방법 을 한 번 실행 한 다음 에 SCROLLSTATE_TOUCH_SCROLL 사건;
3.손가락 이 화면 에 닿 으 면 바로 미 끄 러 지면 처음으로 SCROLLSTATE_TOUCH_SCROLL 사건;
3.시전 SCROLLSTATE_TOUCH_SCROLL 사건 이후 에 도 계속 onScroll 사건 을 여러 번 촉발 합 니 다.SCROLL 을 직접 촉발 하 는 것 이 아 닙 니 다.STATE_FLING 이벤트;
4.스크롤 후 반드시 SCROLL 이 발동 하 는 것 은 아 닙 니 다STATE_FLING 사건 은 손가락 이 미 끄 러 지 는 거리 와 관계 가 있 을 수 있 습 니 다.
5.스크롤 하 는 과정 에서 onScroll 방법 을 여러 번 호출 합 니 다.
6.onScroll 이 여러 번 촉발 하 는 것 을 제외 하고 다른 사건 은 전체 과정 에서 한 번 만 촉발 합 니 다.

좋은 웹페이지 즐겨찾기