Android ListViewを最後までスクロールしたら自動的にデータをロードします。


Androidに詳しい友達は、マイクロブログクライアントでもニュースクライアントでもリストコンポーネントから離れられないことを知っています。リストコンポーネントはAndroidデータの展示において最も重要なコンポーネントと言えます。今日はリストコンポーネントListViewにデータをロードする関連内容について説明します。通常、1つのアプリケーションは、大量のデータを表示する場合、利用可能なすべてのデータをユーザに提示することはない。これは、サービス端末にとってもクライアントにとっても大きな圧力であるため、多くのアプリケーションはバッチロードの形でユーザに必要なデータを取得するために使用される。例えば、マイクロブログクライアントは、ユーザーがリストの一番下にスライドした時に自動的に次のページのデータをロードすることができます。下に「より多くのロード」ボタンを置いて、ユーザーがクリックした後、次のページのデータをロードすることもできます。
今日は例を合わせてListViewを使ってデータを取得する過程を実証します。
新しいloadmoreプロジェクトを作成します。構造図と最終効果図を見てみます。

左の図には三つのレイアウトファイルと一つのAdapterと一つのActivityが含まれています。右の図は私たちが実行した後のメインインターフェースです。
ここで、メインインターフェースのレイアウトファイルであり、ListViewコンポーネントを含んでいます。コードは以下の通りです。

 <?xml version="1.0" encoding="utf-8"?> 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 android:orientation="vertical" 
 android:layout_width="fill_parent" 
 android:layout_height="fill_parent" 
 android:paddingLeft="3dp" 
 android:paddingRight="3dp"> 
 <ListView 
  android:id="@id/android:list" 
  android:layout_width="fill_parent" 
  android:layout_height="wrap_content"/> 
 </LinearLayout> 
ここでは、Androidに内蔵されているリストというIDを引用しています。これは私たちの後にListActivityに使われるため、私たちのMainActivityが引き継いでいます。
そしてラストですitem.xmlは、ListViewの単一リスト項目のレイアウトファイルです。効果図からは、TextViewコンポーネント、list_のみが使用されています。item.xmlコードは以下の通りです。

 <?xml version="1.0" encoding="utf-8"?> 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 android:orientation="vertical" 
 android:layout_width="fill_parent" 
 android:layout_height="fill_parent"> 
 <TextView 
  android:id="@+id/list_item_text" 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
  android:gravity="center" 
  android:textSize="20sp" 
  android:paddingTop="10dp" 
  android:paddingBottom="10dp"/> 
 </LinearLayout> 
右の図のリストの下に他のリスト項目とは異なるボタンがありますが、これはどのような状況ですか?実はこのボタンは私達がListViewの底に追加したものです。ListViewコンポーネントは、上部と下部にカスタマイズしたビューを追加する機能を提供しています。私たちはここのListViewの底にもう一つのビューを追加して、もっと多くのデータをロードします。このビューはload_に対応しています。more.xmlレイアウトファイルのコードは以下の通りです。

 <?xml version="1.0" encoding="utf-8"?> 
 <LinearLayout 
 xmlns:android="http://schemas.android.com/apk/res/android" 
 android:orientation="vertical" 
 android:layout_width="fill_parent" 
 android:layout_height="wrap_content"> 
 <Button 
  android:id="@+id/loadMoreButton" 
  android:layout_width="fill_parent" 
  android:layout_height="wrap_content" 
  android:text="load more" 
  android:onClick="loadMore"/> 
 </LinearLayout> 
次に私達はAdapterを調べます。ListView Adapterコードは以下の通りです。

 package com.scott.loadmore; 
 
 import java.util.List; 
 
 import android.content.Context; 
 import android.view.LayoutInflater; 
 import android.view.View; 
 import android.view.ViewGroup; 
 import android.widget.BaseAdapter; 
 import android.widget.TextView; 
 
 public class ListViewAdapter extends BaseAdapter { 
 private List<String> items; 
 private LayoutInflater inflater; 
  
 public ListViewAdapter(Context context, List<String> items) { 
  this.items = items; 
  inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
 } 
  
 @Override 
 public int getCount() { 
  return items.size(); 
 } 
 
 @Override 
 public Object getItem(int position) { 
  return items.get(position); 
 } 
 
 @Override 
 public long getItemId(int position) { 
  return position; 
 } 
 
 @Override 
 public View getView(int position, View view, ViewGroup parent) { 
  if (view == null) { 
  view = inflater.inflate(R.layout.list_item, null); 
  } 
  TextView text = (TextView) view.findViewById(R.id.list_item_text); 
  text.setText(items.get(position)); 
  return view; 
 } 
  
 /** 
  *       
  * @param item 
  */ 
 public void addItem(String item) { 
  items.add(item); 
 } 
 } 
このListView Adapterは私達のカスタムアダプターです。これはBaseAdapterから継承されています。このアダプタを実装するにはLayout Inflaterのインスタンスとセットオブジェクトを取得するためのContextオブジェクトが必要です。get View方法ではlist_を充填します。item.xmlレイアウトファイルは、リストの各項目のデータ表示を完了します。addItem法は、データをロードする際にデータセットに新しいデータを追加するために使用されます。
最後にMainActivityに来ました。

 package com.scott.loadmore; 
 
 import java.util.ArrayList; 
 
 import android.app.ListActivity; 
 import android.os.Bundle; 
 import android.os.Handler; 
 import android.util.Log; 
 import android.view.View; 
 import android.widget.AbsListView; 
 import android.widget.AbsListView.OnScrollListener; 
 import android.widget.Button; 
 import android.widget.ListView; 
 
 public class MainActivity extends ListActivity implements OnScrollListener { 
 private ListView listView; 
 private int visibleLastIndex = 0; //         
 private int visibleItemCount; //           
 private ListViewAdapter adapter; 
 private View loadMoreView; 
 private Button loadMoreButton; 
 private Handler handler = new Handler(); 
 
 @Override 
 public void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.main); 
  
  loadMoreView = getLayoutInflater().inflate(R.layout.load_more, null); 
  loadMoreButton = (Button) loadMoreView.findViewById(R.id.loadMoreButton); 
 
  listView = getListView();  //  id list ListView 
  
  listView.addFooterView(loadMoreView); //         
 
  initAdapter(); 
  
  setListAdapter(adapter);  //   id list ListView      
  
  listView.setOnScrollListener(this); //       
 } 
  
 /** 
  *        
  */ 
 private void initAdapter() { 
  ArrayList<String> items = new ArrayList<String>(); 
  for (int i = 0; i < 10; i++) { 
  items.add(String.valueOf(i + 1)); 
  } 
  adapter = new ListViewAdapter(this, items); 
 } 
 
 /** 
  *        
  */ 
 @Override 
 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
  this.visibleItemCount = visibleItemCount; 
  visibleLastIndex = firstVisibleItem + visibleItemCount - 1; 
 } 
 
 /** 
  *            
  */ 
 @Override 
 public void onScrollStateChanged(AbsListView view, int scrollState) { 
  int itemsLastIndex = adapter.getCount() - 1; //           
  int lastIndex = itemsLastIndex + 1;  //     loadMoreView  
  if (scrollState == OnScrollListener.SCROLL_STATE_IDLE && visibleLastIndex == lastIndex) { 
  //       ,                 
  Log.i("LOADMORE", "loading..."); 
  } 
 } 
  
 /** 
  *        
  * @param view 
  */ 
 public void loadMore(View view) { 
  loadMoreButton.setText("loading..."); //      loading 
  handler.postDelayed(new Runnable() { 
  @Override 
  public void run() { 
   
   loadData(); 
   
   adapter.notifyDataSetChanged(); //      ,  adapter 
   listView.setSelection(visibleLastIndex - visibleItemCount + 1); //      
   
   loadMoreButton.setText("load more"); //       
  } 
  }, 2000); 
 } 
  
 /** 
  *        
  */ 
 private void loadData() { 
  int count = adapter.getCount(); 
  for (int i = count; i < count + 10; i++) { 
  adapter.addItem(String.valueOf(i + 1)); 
  } 
 } 
 } 
コードに示されているように、私達はオンクリアーメソッドを呼び出した時にlistViewコンポーネントを取得し、その下のビューをloadMoreViewとして設定します。ボタンを含みます。クリックするとloadMoreメソッドの呼び出しをトリガします。またlistViewのためにアダプターを設置した時に、スライドイベントモニターを設置しました。スライドリストの時にOScrrollを呼び出します。スライディング状態が変化すると、オンスクリーン・チェーンが呼び出されます。
このロードプロセスを実証します。

図のように、ボタンをクリックしたらロード動作があり、ロードが完了したら右の図のように、新しいデータが元のデータの直後にあります。最後までスライドします。ボタンを押しても作業できます。

最後に、スライドリストの最後の部分をテストして、それから放して、コンソールは次のように印刷します。

以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。