2016-06-18 14 views
6

È la prima volta che utilizzo il listener di onscroll. Il mio problema è come recuperare 20 nuove righe ogni volta che si scorre verso il basso?recupera solo 20 righe dal server con setOnScrollListener

Capisco quando farò scorrere verso il basso la vista della griglia questo codice verrà eseguito.

public void onScroll(AbsListView view, int firstVisibleItem, 
          int visibleItemCount, int totalItemCount) { 
      // TODO Auto-generated method stub 

      this.currentFirstVisibleItem = firstVisibleItem; 
      this.currentVisibleItemCount = visibleItemCount; 
      this.totalItem = totalItemCount; 

      if ((totalItemCount - visibleItemCount) <= (firstVisibleItem + 20)) { 
       // the below when executed will get all the rows ,I only need 20 rows 
      handler.execute().get(); 

      } 
     } 

questo è il mio codice

// the load more in the grid view, fetch new images. 
mGridView.setOnScrollListener(new AbsListView.OnScrollListener() { 
    private int currentVisibleItemCount; 
    private int currentScrollState; 
    private int currentFirstVisibleItem; 
    private int totalItem; 
    private LinearLayout lBelow; 

    @Override 
    public void onScrollStateChanged(AbsListView view, int scrollState) { 
     // TODO Auto-generated method stub 
     this.currentScrollState = scrollState; 
     this.isScrollCompleted(); 
    } 

    @Override 
    public void onScroll(AbsListView view, int firstVisibleItem, 
         int visibleItemCount, int totalItemCount) { 
     // TODO Auto-generated method stub 

     this.currentFirstVisibleItem = firstVisibleItem; 
     this.currentVisibleItemCount = visibleItemCount; 
     this.totalItem = totalItemCount; 

     if ((totalItemCount - visibleItemCount) <= (firstVisibleItem + 20)) { 
      // load new 20 row but how to do that 

     } 
    } 

    private void isScrollCompleted() { 
     if (totalItem - currentFirstVisibleItem == currentVisibleItemCount 
       && this.currentScrollState == SCROLL_STATE_IDLE) { 
      Log.d("a", "poooppii"); 

     } 
    } 

    ; 
}); 

è qui che il collegamento avviene

protected void showList(){ 
     try { 

      JSONObject jsonObj = new JSONObject(myJSON); 
      peoples = jsonObj.getJSONArray("result"); 
      System.out.println("Length:"+peoples.length()); 
      int J_length=peoples.length()-1; 


      jsonObj= peoples.getJSONObject(J_length); 


       Listitem = new ArrayList<Listitem>(); 

       for (int i = 0; i < peoples.length(); i++) { 
        JSONObject c = peoples.getJSONObject(i); 

        String id = c.getString("id"); 
        String url = c.getString("url"); 

        int intid = 0; 
        try { 
         intid = Integer.parseInt(id.toString()); 
        } catch (NumberFormatException nfe) { 
         System.out.println("Could not parse " + nfe); 
        } 

        Listitem.add(new Listitem(id, url)); 
        System.out.println(Listitem); 
       } 
      //} 
      if (mListener != null) 
        mListener.myMethod(Listitem); 


     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 

    } 
+0

perché non si sta utilizzando l'adattatore invece di ascoltatori di scorrimento.Raccomando l'adattatore, perché qui questo problema può essere risolto molto facilmente e avrai anche un'esperienza migliore. – Neo

+0

puoi per favore farmi vedere un esempio di come usarlo su un adattatore? – Moudiz

+0

Ho pubblicato il mio codice di lavoro per la risoluzione dei problemi simile con l'aiuto dell'adattatore, spero che ti possa aiutare :) – Neo

risposta

3

Ecco un codice di lavoro, Gentilmente modificare secondo il vostro uso -

Lasciate assume segue è il modello -

public class MyModel { 
    String name; 
} 

È necessario un'interfaccia -

public interface PagingListener<T> { 
    void onItemUpdate(ArrayList<T> allData); 
} 

Progettare la scheda In questo modo -

public class CouponsAdapter extends RecyclerView.Adapter<CouponsAdapter.CouponHolder> implements View.OnClickListener, PagingListener<MyModel> { 
    private final static int TYPE_LOADING = 0; 
    private final static int TYPE_DATA = 1; 
    private FragmentActivity activity; 
    private LayoutInflater inflater; 
    private PagingRequestHandler<MyModel> pagingRequestHandler; 
    private ArrayList<MyModel> data = null; 

    public CouponsAdapter(FragmentActivity activity) { 
     this.activity = activity; 
     inflater = LayoutInflater.from(activity); 
     this.data = new ArrayList<>(); 
     this.pagingRequestHandler = new PagingRequestHandler<>(data, this); 
    } 

    @Override 
    public int getItemViewType(int position) { 
     return position >= data.size() ? TYPE_LOADING : TYPE_DATA; 
    } 

    @Override 
    public CouponHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view; 
     if (viewType == TYPE_DATA) { 
      view = inflater.inflate(R.layout.item_coupons_card_block, parent, false); 
     } else { 
      view = inflater.inflate(R.layout.item_drawer_payment_loading, parent, false); 
     } 
     return new CouponHolder(view, viewType); 
    } 

    @Override 
    public void onBindViewHolder(CouponHolder holder, int position) { 
     if (getItemViewType(position) == TYPE_DATA) { 
      //Bind your view here 
     } 
     pagingRequestHandler.checkAndMakeRequestForMoreData(position); //Will check and make request 
    } 

    @Override 
    public int getItemCount() { 
     return data.size() + (pagingRequestHandler.isNoMoreDataLeft() ? 0 : 1); // If no data then it will return 1 to show loading 
    } 

    @Override 
    public void onClick(View v) { 
    } 

    @Override 
    public void onItemUpdate(ArrayList<MyModel> allData) { 
     this.data = allData; // will update data with updated content 
     notifyDataSetChanged(); 

    } 


    public class CouponHolder extends RecyclerView.ViewHolder { 
     public CouponHolder(View itemView, int itemType) { 
      super(itemView); 
      if (itemType == TYPE_DATA) { 
      } 
     } 
    } 
} 

E ora questo è il gestore della richiesta di paging, che non mancherà di tenere traccia sul numero di pagina e farà richiesta di pagina successiva -

public class PagingRequestHandler<T> { 
    public static final int PAGE_SIZE = 10; 
    private final PagingListener listener; 
    private final ArrayList<MyModel> arrayList; 
    private final String url = "Your Url here"; 
    private boolean noMoreDataLeft; 
    private int pagingIndex = 0; 
    private boolean requestGoingOn; 


    public PagingRequestHandler(ArrayList<MyModel> data, PagingListener<MyModel> listener) { 
     this.listener = listener; 
     this.arrayList = data; 
     fetchMoreData(); 

    } 

    private void fetchMoreData() { 
     requestGoingOn = true; 
     Call<MyModel[]> getCoupons = Utils.getRetrofit().getCoupons(url + "/" + pagingIndex); // I am using retrofit for network call, you can use your own 
     getCoupons.enqueue(new Callback<MyModel[]>() { 
      @Override 
      public void onResponse(Response<MyModel[]> response, Retrofit retrofit) { 
       try { 
        requestGoingOn = false; 
        MyModel[] couponModelDses = response.body(); 
        if (couponModelDses != null) { 
         for (MyModel couponModelDse : couponModelDses) { 
          arrayList.add(couponModelDse); 
         } 
         if (couponModelDses.length < PAGE_SIZE) 
          noMoreDataLeft = true; 
         listener.onItemUpdate(arrayList); 
        } 
       } catch (Exception e) { 
        e.printStackTrace(); 

       } 
      } 

      @Override 
      public void onFailure(Throwable t) { 
       requestGoingOn = false; 
      } 
     }); 
    } 

    public boolean isNoMoreDataLeft() { 
     return noMoreDataLeft; 
    } 

    public void checkAndMakeRequestForMoreData(int position) { 
     if (!noMoreDataLeft && !requestGoingOn && position > (PAGE_SIZE * pagingIndex)) { 
      if ((position % PAGE_SIZE) > (int) (PAGE_SIZE * .7)) { 
       pagingIndex++; 
       fetchMoreData(); 
      } 
     } 
    } 
} 

Come funziona - l'adattatore è inizializzazione del gestore, che rendono chiamata di rete per la prima volta. L'adattatore ora chiama api del gestore per verificare se il 70% della pagina scorre su ogni onBind. Ora se il 70% dei dati è stato mostrato, rende la chiamata di rete againe e rende una variabile chiamata requestGoingOn true, così puoi mostrare un loader in lista. Se la richiesta è stata completata, il gestore sta aggiungendo i dati all'array ed all'aggiornamento dell'adattatore chiamando il callback onItemUpdate.

auguriamo che contribuiscano, per favore fatemi sapere se avete bisogno di ulteriore assistenza :)

+0

grazie lo guarderò io – Moudiz

+0

@Moudiz è il tuo problema risolto? – Neo

+0

ancora non ero ancora occupato ultimamente, domani lo controllerò grazie – Moudiz

5

È necessario mantenere base e limit per il carico dei dati. Inizializza la tua base e la variabile limite.

int base = 0, limit = 20; 

Aumenta il tuo variabile base ogni volta che il caricamento di nuovi elementi.

base = base + limit; 
handler.execute().get(); 

Passo base e limit variabile nel API chiamata, in modo che si può utilizzare in query da API lato.

Nota: base è un valore da cui è necessario iniziare la ricerca dei valori. limite è un valore per il numero di righe da recuperare.

Vedere this per la query limite in sqlite.
Vedere this per la query limite in MySql.
Vedere this per la query limite in SQL.

+1

avevi ragione mi manca il limite e la base, tuttavia dopo aver provato alcuni esempi ho notato che il mio codice precedente non funzionerà perché setOnScrollListener è privato per visualizzazione recycler. ricerca malata di esempi sul web. avete un esempio consigliato per recyclerview e caricamento su scroll? – Moudiz

+0

[questo] (http://stackoverflow.com/a/26643292/3134215) potrebbe aiutarti –

Problemi correlati