2012-03-15 3 views
1

私は LazyList EndlessListを作成しようとしていますが、セクションアダプタを使用しています...セクションは、インターネットからダウンロードされるアイテムのページになります。MergeAdapter/SectionedAdapterの更新

私は、MergeAdapterまたは廃止予定のSectionedAdapter(Mark Murphyによる)の両方を使用して、その基本的な要点を実装しようとしました。しかし、私は両方の問題に直面しています。

1)SectionedAdapterを使用すると、最初のページが正常に読み込まれますが、2番目のページではこの例外が発生します。研究の時間後、私はそれを実現してきました

Uncaught handler: thread main exiting due to uncaught exception 
java.lang.ArrayIndexOutOfBoundsException 
at android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:3572) 
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:2487) 
at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:2353) 
at android.os.Handler.handleCallback(Handler.java:587) 
at android.os.Handler.dispatchMessage(Handler.java:92) 
at android.os.Looper.loop(Looper.java:123) 
at android.app.ActivityThread.main(ActivityThread.java:4363) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:521) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
at dalvik.system.NativeStart.main(Native Method) 

は間違っgetViewTypeCount()値とは何かです。しかし、正しく実装する方法はわかりません。

2)次に、MergeAdapterを使ってみましたが、単純に悪化させました。セクションもランダムな間隔で表示されます。

私は実装を示すために小さなサンプルプログラムを作成しました。

import java.math.BigInteger; 
import java.util.ArrayList; 
import java.util.List; 

import android.app.ListActivity; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.Window; 
import android.widget.AbsListView; 
import android.widget.AbsListView.OnScrollListener; 
import android.widget.ArrayAdapter; 
import android.widget.TextView; 

public class LazySectionListActivity extends ListActivity implements 
     OnScrollListener { 

    private int mPrevItemCount; 
    private int nextPrimes = 0; 
    private final int MAX = 100; 
    private final SectionAdapter adapter = new SectionAdapter(); 

    // private final MergeAdapter adapter = new MergeAdapter(); 

    private class SectionAdapter extends SectionedAdapter { 

     @Override 
     protected View getHeaderView(String caption, int index, 
            View convertView, ViewGroup parent) { 
      TextView tv = new TextView(LazySectionListActivity.this); 
      tv.setText(caption); 
      return tv; 
     } 

    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 
     setProgressBarIndeterminate(true); 
     setContentView(R.layout.main); 
     getListView().setOnScrollListener(this); 
     setListAdapter(adapter); 
     new NextThousandPrimes(nextPrimes).execute(); 
     nextPrimes += MAX; 
    } 

    @Override 
    public void onScroll(AbsListView view, int firstVisibleItem, 
         int visibleItemCount, int totalItemCount) { 

     if(firstVisibleItem + visibleItemCount >= totalItemCount 
      && mPrevItemCount != totalItemCount) { 
      new NextThousandPrimes(nextPrimes).execute(); 
      nextPrimes += MAX; 
      mPrevItemCount = totalItemCount; 
     } 

    } 

    @Override 
    public void onScrollStateChanged(AbsListView view, int scrollState) { 

    } 

    private class NextThousandPrimes extends AsyncTask<Void, Void, Void> { 
     private final int start; 
     private final List<String> primes = new ArrayList<String>(); 

     public NextThousandPrimes(int nextPrimes) { 
      this.start = nextPrimes; 
     } 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      setProgressBarIndeterminateVisibility(true); 
     } 

     @Override 
     protected Void doInBackground(Void... params) { 
      for(int s = start; s < start + MAX; s++) 
       if(BigInteger.valueOf(s).isProbablePrime(1)) { 
        primes.add(String.valueOf(s)); 
       } 
      return null; 
     } 

     @Override 
     protected void onPostExecute(Void result) { 
      super.onPostExecute(result); 
      setProgressBarIndeterminateVisibility(false); 
      //TextView view = new TextView(LazySectionListActivity.this);//for merge adapter, use the commented code 
      //view.setText(String.format("%d-%d", start, start + MAX)); 
      // adapter.addView(view); 
      // adapter.addAdapter(new 
      // ArrayAdapter<String>(LazySectionListActivity.this, 
      // android.R.layout.simple_list_item_1, 
      // primes)); 
      adapter.addSection(String.format("%d-%d", start, start + MAX), 
           new ArrayAdapter<String>(LazySectionListActivity.this, 
                 android.R.layout.simple_list_item_1, 
                 primes)); 
      adapter.notifyDataSetChanged(); 

     } 
    } 
} 

私は何が欠けていますか?どんな助けもありがとうございます。前もって感謝します。 MergeAdapterドキュメントに記載されているように

+0

具体的には、「レイジーリスト」とはどういう意味ですか? – CommonsWare

+0

おっと、申し訳ありませんが、私はエンドレスリストを意味しました。 – st0le

答えて

5

あなたはリストビューでMergeAdapterを関連付けるためにsetListAdapter()を呼び出す前にMergeAdapterに内容を注ぐ必要があります。 AndroidではgetViewTypeCount()を1回しか呼び出しず、ビューやアダプターを追加するとビューの種類が増えるため、この制限が必要です。

MergeAdapterしたがって、可能なビューの種類がいくつあるかわからないため、MergeAdapterは無限の設定では機能しません。

あなたはニーズよりも大きくなると、それが動作するかどうかを確認します 確信しているいくつかの値になるようにgetViewTypeCount()を配線あなたがMergeAdapterのコピーをハッキングしようとするために歓迎され

、。言い分が変わると、あなたの走行距離は変わるかもしれません:-)

+0

こんにちはマーク、AFAIK 'getViewTypeCount()'は、ListView全体に存在するさまざまな種類のビューを参照します。しかし、私の場合、私は2つしか知りません(セクションと実際のデータリスト項目)。 MergeAdapterが 'Viewtypecount = 2'を返すなら、それで十分ではないでしょうか? – st0le

+0

@ st0le: 'getViewTypeCount()'と 'getItemViewType()'をオーバーライドし、それらの値を手動で管理する場合にのみ、 'MergeAdapter'は本当に必要なく、あなた自身ですべて行うことができます。 – CommonsWare

+0

ああ、私はあなたのセクションアダプタをハッキングしようとします。再度、感謝します。 – st0le