2013-10-31 27 views
0

我正在嘗試更新我的列表視圖以創建「無限滾動」。什麼情況是,前40個結果加載罰款,當我到達滾動的底部,未來40個結果取代第一40 ...從onScrollListener追加列表視圖

我要的是第二組的40個結果添加到第一40,所以我有一個無盡的列表和能夠回滾到列表的開頭。

我下面張貼我的代碼。謝謝!

public class SearchResults extends Activity implements BannerAdListener, OnScrollListener{ 

    private LinearLayout bottomNav; 
    private ListView ringtoneList; 
    private int start = 0, num = 40, curPage = 1; 
    private Handler handler = new Handler(); 
    private ProgressDialog progressDialog = null; 
    private ArrayList<Ringtone> ringtones; 
    private MoPubView moPubView; 
    private String searchString; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     Bundle extras = getIntent().getExtras(); 
     if (extras == null) { 
      // no search string defined 
      finish(); 
     } else { 
      searchString = extras.getString("search_string"); 
     } 

     setContentView(R.layout.search_results);  

     ringtoneList = (ListView)findViewById(R.id.ringtone_list); 
     ringtoneList.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> av, View view, int position, long id) { 
       Intent i = new Intent(SearchResults.this, RingtoneView.class); 
       i.putExtra("ringtone", ringtones.get(position)); 
       startActivity(i); 
      } 
     }); 

     performSearch(); 

     moPubView = (MoPubView) findViewById(R.id.adview); 
     moPubView.setAdUnitId(Utils.MoPubBannerId); 
     moPubView.loadAd(); 
     moPubView.setBannerAdListener(this); 

     ringtoneList.setOnScrollListener(this); 

    } 

    public void onScroll(AbsListView view, int firstVisible, final int visibleCount, int totalCount) { 

      Log.i("List", "firstVisible="+firstVisible+" visibleCount="+visibleCount+" totalCount="+totalCount); 

      boolean loadMore = firstVisible + visibleCount >= totalCount; 

      if(loadMore) { 

       Log.i("List", "Loading More Results");     

       curPage++; 
       start = num * (curPage-1); 

       new Thread() { 

        public void run() { 

         ringtones = Utils.search(start, num, searchString); 

         if (ringtones != null && ringtones.size() > 0) { 

          handler.post(new Runnable() { 
           public void run() { 
            ringtoneList.setAdapter(new RingtoneRowAdapter(SearchResults.this, ringtones)); 
           } 
          }); 

         } else { 

          handler.post(new Runnable() { 
           public void run() { 
            new AlertDialog.Builder(SearchResults.this) 
            .setTitle(getResources().getString(R.string.context_info)).setMessage(getResources().getString(R.string.context_noresult)) 
            .setPositiveButton(getResources().getString(R.string.context_ok), null).show(); 
           } 
          }); 

         } 

        } 
       } 

       .start(); 
     } 
    } 

    public void onScrollStateChanged(AbsListView v, int s) { } 

    private void performSearch() { 
     progressDialog = ProgressDialog.show(SearchResults.this, getResources().getString(R.string.loading_message), getResources().getString(R.string.loading_search), true); 
     new Thread() { 
      public void run() { 
       ringtones = Utils.search(start, num, searchString); 
       if (ringtones != null && ringtones.size() > 0) { 
        updateList(); 
       } else { 
        handler.post(new Runnable() { 
         public void run() { 
          new AlertDialog.Builder(SearchResults.this) 
          .setTitle(getResources().getString(R.string.context_info)).setMessage(getResources().getString(R.string.context_noresult)) 
          .setPositiveButton(getResources().getString(R.string.context_ok), null).show(); 
          ringtoneList.setVisibility(View.INVISIBLE); 
          bottomNav.setVisibility(View.INVISIBLE); 
         } 
        }); 
       } 
       progressDialog.dismiss(); 
      } 
     }.start(); 
    } 

    private void updateList() { 
     handler.post(new Runnable() { 
      public void run() { 
       //Log.d("search", "ringtones.size() " + ringtones.size()); 
       ringtoneList.setVisibility(View.VISIBLE); 
       ringtoneList.setAdapter(new RingtoneRowAdapter(SearchResults.this, ringtones)); 
      } 
     }); 
    } 

} 

請幫忙!謝謝!

回答

0

雖然我不能100%肯定,我認爲你的問題是與事實,你設置一個新的適配器,只有具有鈴聲,在負載部分做。它可能與這個片段有關:

ringtones = Utils.search(start, num, searchString); 

if (ringtones != null && ringtones.size() > 0) { 

    handler.post(new Runnable() { 
     public void run() { 
      ringtoneList.setAdapter(new RingtoneRowAdapter(SearchResults.this, ringtones)); 
     } 
    }); 

} 

而不是把一個全新的鈴聲陣列,你應該添加到你已經擁有的。你ringtones變量已經是一個實例變量,所以我敢肯定,如果你改變了這一行:

ringtones = Utils.search(start, num, searchString); 

以下幾點:

ringtones.addAll(Utils.search(start, num, searchString)); 

它可能會解決你的問題。

+0

我希望它能工作,因爲那是最簡單的解決方案,但是,它給了我adAll線上的java.lang.NullPointerException錯誤 – user2727376

+0

在你的'onCreate()'中,嘗試把'ringtones = new ArrayList ()'。我可以告訴你的問題是你沒有實例化它。我只是在調用'setContentView()' –

+0

謝謝你,然後把它放在它:) – user2727376

0

你的代碼是有點亂,但你updateList方法是創建一個新RingtoneRowAdapter。你應該將項目添加到列表和電話

mRingtoneRowAdapter.notifyDatasetChanged(); 

會告訴適配器有很多的內部的東西在適配器的級別發生相處的新觀點(如果需要)。所以它有點:

private void updateList() { 
     handler.post(new Runnable() { 
      public void run() { 
       if (mAdapter == null) { 
        mAdapter = new RingtoneRowAdapter(SearchResults.this, ringtones); 
        ringtoneList.setAdapter(mAdapter); 
       } else { 
        mAdapter.notifyDataSetChanged(); 
       } 
       ringtoneList.setVisibility(View.VISIBLE); 
      } 
     }); 
    } 

當然,正如已經建議,不要始終啓動您的鈴聲數組。只需將數據添加到它。

你不需要(大部分時間)隱藏列表,你可以在你的佈局添加,查看任何與一個ID(包括一個完整的佈局!):

android:id="@android:id/empty" 

如果你的ListView有一個id:「id =」@ id/android:list「,你在ListFragment或ListActivity中,那麼當列表爲空時,將顯示」空白「佈局(可以是一個虛擬查看你是否不想看到它)。

只是建議:)

UPDATE:爲了您的空,我看到的邏輯是有點怪異,因爲我們不知道您的應用程序的要求(即,如果有該怎麼辦沒有結果,如果結果無效怎麼辦等)我假設你只是想確保它的工作原理,並在以後處理。

所以考慮到這一點,我看到兩個問題。

  1. 我假設你的Utils.search方法可以返回null,因爲你正在檢查它。對我來說,感覺很奇怪,我寧願返回一個空數組,表示搜索沒有產生結果;除了這個小小的評論之外,如果searchString爲null或者沒有,你不檢查(或者我們不知道,因爲我們沒有看到你的搜索方法的來源)。
  2. 您沒有提供一個堆棧跟蹤,所以我們不能說在空正在發生的事情(無論是內部搜索還是?)

一個快速的解決辦法是在搜索之前檢查空...我會親自做這個INSIDE搜索功能。

喜歡的東西:

public ArrayList<Ringtone> search(final int start, final int num, final String searchString) { 

    if (searchString == null) { 
     //DECIDE WHAT YOU WANT TO DO, EITHER: 
     return null; 
     // OR YOU CAN RETURN AN EMPTY ARRAY 
     return new ArrayList<Ringtone>(); 
    } 
    // You should check for these (change according to your rules) 
    if (start < 0) { 
     start = 0; // protect yourself from bad data. 
    } 
    if (num < 0) { 
     num = 0; 
    } 
    /// THE REST OF YOUR search FUNCTION 

    return <your array> 
} 

現在,另一件事是,你可能想搜索返回增量結果(所以你可以將它們添加到您的陣列(而不是每次都返回一個新的數組)對於。 ,正如已經暗示的那樣,使用addAll技巧,但是不要返回null,返回一個新的空數組,所以如果沒有別的東西需要添加,就沒有任何傷害。

+0

我試過這種方法,它似乎工作,但現在ringtones.addAll(Utils.search(start,num,searchString));返回給我一個NullPointerException ...任何想法? – user2727376

+0

其中之一是在某些時候爲零:鈴聲數組,您的Utils似乎是一個單身人士,所以我想它沒關係。開始,num或searchString爲空/無效。添加一個斷點並檢查空值,這是Java,所以一切都可以爲空! :)我的猜測是searchString。你在做searchString = extras.getString(「search_string」);但如果search_string不存在......你的字符串將爲空。 –

+0

謝謝。我用你的updateList()方法和Andrew的實例化數組的幫助。 – user2727376