1

PulltoRefresh と EndlessAdapter を使用しようとしていますが、アプリを初めて実行すると、リストは非常にうまく読み込まれますが、最後にさらにデータを読み込むとクラッシュします。

ライブラリ EndLessAdapter: https://github.com/commonsguy/cwac-endless

ライブラリ PulltoRefresh: https://github.com/chrisbanes/Android-PullToRefresh

PullToRefresh なしで動作していました。

そのアプリを初めて実行すると、次のように呼び出されます。

  1. getPendingView
  2. MyAsyncTask
  3. hasmoredata を返す
  4. postOnExecute を呼び出す - リスナー
  5. OnItemsReady を呼び出す
  6. DemoAdapter.notydatasetchanged を設定します

リストの終わりを取得すると、次のように呼び出します。

  1. getPendingView
  2. MyAsyncTask
  3. hasmoredata を返す
  4. IndexOutofBoundException を与える

スタックトレース:

01-28 11:12:15.273: E/AndroidRuntime(12735): FATAL EXCEPTION: main
01-28 11:12:15.273: E/AndroidRuntime(12735): java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
01-28 11:12:15.273: E/AndroidRuntime(12735):    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
01-28 11:12:15.273: E/AndroidRuntime(12735):    at java.util.ArrayList.get(ArrayList.java:311)
01-28 11:12:15.273: E/AndroidRuntime(12735):    at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:225)
01-28 11:12:15.273: E/AndroidRuntime(12735):    at android.widget.AbsListView.obtainView(AbsListView.java:1592)
01-28 11:12:15.273: E/AndroidRuntime(12735):    at android.widget.ListView.makeAndAddView(ListView.java:1782)
01-28 11:12:15.273: E/AndroidRuntime(12735):    at android.widget.ListView.fillDown(ListView.java:705)

PullToRefreshListinViewPager サンプルの内部:

public View instantiateItem(ViewGroup container, int position) {
    PullToRefreshListView plv = null;
    Context context = container.getContext();

    plv = (PullToRefreshListView) LayoutInflater.from(context).inflate(
                        R.layout.layout_listview_in_viewpager, container, false);
    endlessList = new ArrayList<HashMap<String, String>>(); 
    demoAdapter = new DemoAdapter(context, endlessList); 
    demoAdapter.setRunInBackground(false);
    plv.setAdapter(demoAdapter);

    plv.setOnRefreshListener(BaseSampleActivity.this);

    // Now just add ListView to ViewPager and return it
    container.addView(plv, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    return plv;
}

EndLessAdapter:

private class DemoAdapter extends EndlessAdapter implements IItemsReadyListener{

      private RotateAnimation rotate=null;
      private View pendingView=null;
      private ArrayList<HashMap<String, String>> data;
      private List<HashMap<String, String>> mOriginalNames;
      private boolean hasMoreData=true;
      private Context mContext;

      DemoAdapter(Context context, ArrayList<HashMap<String, String>> d) {

        super(new LazyAdapter(context, d));
        this.data = d;
        this.mContext = context;
        rotate=new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF,
                  0.5f, Animation.RELATIVE_TO_SELF,
                  0.5f);

        rotate.setRepeatMode(Animation.RESTART);
        rotate.setRepeatCount(Animation.INFINITE);
      }

      @Override
      protected View getPendingView(ViewGroup parent) {
          View row = LayoutInflater.from(mContext).inflate(R.layout.row, null);

              View child=row.findViewById(android.R.id.text1);

              child.setVisibility(View.GONE);

              child=row.findViewById(R.id.throbber);
              child.setVisibility(View.VISIBLE);
              child.startAnimation(rotate);
            return(row);
      }



      @Override
      protected boolean cacheInBackground() {
        if(isNetworkOnline() == true){
          new MyAsyncTask(this, data.size()).execute();
        }
        return hasMoreData;
      }

      public void onItemsReady(ArrayList<HashMap<String, String>> data) {
          endlessList.addAll(data);
          demoAdapter.onDataReady();  // Tell the EndlessAdapter to remove it's pending
                                  // view and call notifyDataSetChanged()
          hasMoreData = endlessList.isEmpty();
        }

      @Override
      protected void appendCachedData() {
        if (getWrappedAdapter().getCount()<75) {
          @SuppressWarnings("unchecked")
          LazyAdapter a=(LazyAdapter)getWrappedAdapter();
          for (int i = 0; i < data.size(); i++) {
              a.add(data.get(i));
          }
        }
      }
    }

非同期タスク:

private static class MyAsyncTask extends AsyncTask<Void,Void,ArrayList<HashMap<String, String>>>{
        IItemsReadyListener listener;

        int startPoint;

        public MyAsyncTask(IItemsReadyListener listener, int startPoint) {
            // TODO Auto-generated constructor stub
            this.listener = listener;
            this.startPoint = startPoint;
        }

        @Override
        protected ArrayList<HashMap<String, String>> doInBackground(Void... params) {

            XMLParser parser = new XMLParser();
            String xml = parser.getXmlFromUrl(URL); // getting XML from URL
            Document doc = parser.getDomElement(xml); // getting DOM element

            NodeList nl = doc.getElementsByTagName(KEY_SONG);
            // looping through all song nodes <song>
            for (int i = 0; i < 10; i++) {
                // creating new HashMap
                HashMap<String, String> map = new HashMap<String, String>();
                Element e = (Element) nl.item(i);
                // adding each child node to HashMap key => value
                map.put(KEY_ID, parser.getValue(e, KEY_ID));
                map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
                map.put(KEY_ARTIST, parser.getValue(e, KEY_ARTIST));
                map.put(KEY_DURATION, parser.getValue(e, KEY_DURATION));
                map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL));
                // adding HashList to ArrayList
                endlessList.add(map);
            }
            return (endlessList);
        }




        @Override
        protected void onPostExecute(ArrayList<HashMap<String, String>> result)
        {
            listener.onItemsReady(endlessList);
             // Getting adapter by passing xml data ArrayList
            if (demoAdapter != null) 
            {
                demoAdapter.notifyDataSetChanged();
            }

        }
}

アップデート:

私はただ変更します:

      @Override
      protected boolean cacheInBackground() throws Exception {
        if(isNetworkOnline() == true){
          new MyAsyncTask(this).execute();
        }
        if (getWrappedAdapter().getCount()<75) {
            return(true);
          }
        throw new Exception("Gadzooks!");

        }

より多くのコンテンツをロードするようになりましたが、3 回ロードして最終段階に入ると、例外 Gadzooks がスローされ、同じ IndexOutofBoundException が表示されます。

cacheinBackground が false を返すたびにクラッシュすることを知っています。

4

0 に答える 0