2016-04-07 10 views
-1

Ich möchte endlos scrollen mit Adaptern & RecyclerViews und ich hole meine Artikel mit Volley aus JSON. Obwohl ich diese Anleitungen (Codepath und github) gelesen habe, finde ich es schwierig, sie auf mein eigenes Szenario anzuwenden.Endloses Scrollen in RecyclerView: Wie soll ich das umsetzen?

Die URL meiner json hat dieses Format: https://example.com/json/items?page=1, https://example.com/json/items?page=2, https://example.com/json/items?page=3 usw.

Im Folgenden die Codes verwende ich:

MainActivity

public class MainActivity extends AppCompatActivity { 

    private final String TAG = "MainActivity"; 

    private int number = 1; 

    //Creating a list of videos 
    private List<VideoItems> mVideoItemsList; 

    //Creating Views 
    private RecyclerView recyclerView; 
    private RecyclerView.Adapter adapter; 
    private RecyclerView.LayoutManager layoutManager; 
    private ProgressDialog mProgressDialog; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Log.d(TAG, "onCreate called"); 

     //Initializing Views 
     recyclerView = (RecyclerView) findViewById(R.id.video_recycler); 
     LinearLayoutManager layoutManager = new LinearLayoutManager(this); 
     recyclerView.setLayoutManager(layoutManager); 


     // This method was copied from codepath (above url) 
     // Add the scroll listener 
     recyclerView.addOnScrollListener(new EndlessRecyclerViewScrollListener(layoutManager) { 

      @Override 
      public void onLoadMore(int page, int totalItemsCount) { 
       // Triggered only when new data needs to be appended to the list 
       // Add whatever code needed to append new items of the list 
       customLoadMoreDataFromApi(page); 
      } 
     }); 




     //Initializing the videolist 
     mVideoItemsList = new ArrayList<>(); 
     adapter = new VideoAdapter(mVideoItemsList, this); 

     recyclerView.setAdapter(adapter); 

     if (NetworkCheck.isAvailableAndConnected(this)) { 

      //Calling method to get data 
      getData(); 
     } else { 
      //Codes for building Alert Dialog 
      alertDialogBuilder.setPositiveButton(R.string.alert_retry, new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        if (!NetworkCheck.isAvailableAndConnected(mContext)) { 
         alertDialogBuilder.show(); 
        } else { 
         getData(); 
        } 

       } 
      }); 
      alertDialogBuilder.setNegativeButton(R.string.alert_cancel, new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        finish(); 

       } 
      }); 
      alertDialogBuilder.show(); 

     } 


    } 

    public int getNumber() { 
     return number++; 
    } 

    public void setNumber(int number) { 
     this.number = number; 
    } 

    // This method was copied from codepath (above is url) 
    // Append more data into the adapter 
    // This method probably sends out a network request and appends new data items to your adapter; 
    public void customLoadMoreDataFromApi (int offset) { 
     // Send an API request to retrieve appropriate data using the offset value as a parameter. 
     // Deserialize API request and then construct new objects to append to the adapter. 
     // Add the new objects to the data source for adapter 
     mVideoItemsList.addAll(moreVideos); 
     // For efficiency purpose, notify the adapter of the only elements inserted that got changed 
     // curSize will be equal to the index of the first element inserted because the list is 0-indexed 
     int curSize = adapter.getItemCount(); 
     adapter.notifyItemRangeChanged(curSize, mVideoItemsList.size() - 1); 
    } 

    //This method will get data from the web api 
    private void getData(){ 


     Log.d(TAG, "getData called"); 
     //Codes for Showing progress dialog 

     //Creating a json request 
     JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(ConfigVideo.GET_URL + getNumber(), 
       new Response.Listener<JSONArray>() { 
        @Override 
        public void onResponse(JSONArray response) { 
         Log.d(TAG, "onResponse called"); 
         //Dismissing the progress dialog 
         if (mProgressDialog != null) { 
          mProgressDialog.hide(); 
         } 
        //calling method to parse json array 
         parseData(response); 

        } 
       }, 
       new Response.ErrorListener() { 
        @Override 
        public void onErrorResponse(VolleyError error) { 

        } 
       }); 

     //Creating request queue 
     RequestQueue requestQueue = Volley.newRequestQueue(this); 

     //Adding request to the queue 
     requestQueue.add(jsonArrayRequest); 

    } 

    //This method will parse json data 
    private void parseData(JSONArray array){ 
     Log.d(TAG, "Parsing array"); 

     for(int i = 0; i<array.length(); i++) { 
      VideoItems videoItem = new VideoItems(); 
      JSONObject jsonObject = null; 
      try { 
       jsonObject = array.getJSONObject(i); 
       videoItem.setVideo_title(jsonObject.getString(ConfigVideo.TAG_VIDEO_TITLE)); 
       videoItem.setVideo_body(jsonObject.getString(ConfigVideo.TAG_VIDEO_BODY)); 

      } catch (JSONException w) { 
       w.printStackTrace(); 
      } 
      mVideoItemsList.add(videoItem); 


     } 

     adapter.notifyItemRangeChanged(0, adapter.getItemCount()); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Log.d(TAG, "onDestroy called"); 
     if (mProgressDialog != null){ 
      mProgressDialog.dismiss(); 
      Log.d(TAG, "mProgress dialog dismissed"); 

     } 
    } 

} 

EndlessRecyclerViewScrollListener Der Link zum Code lautet EndlessRecyclerViewScrollListener.

In dem in meinem Projekt habe ich alle Codes gelöscht, die GridLayoutManager und StaggeredGridLayoutManager betreffen, da ich sie nicht brauchen werde.

Videoadapter

public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.ViewHolder>{ 

    private ImageLoader imageLoader; 
    private Context mContext; 

    //List of videos 
    private List<VideoItems> mVideoItems; 

    public VideoAdapter(List<VideoItems> videoItems, Context context) { 
     super(); 

     // Getting all videos 
     this.mVideoItems = videoItems; 
     this.mContext = context; 
    } 

    @Override 
    public ViewHolder onCreateViewHolder (ViewGroup parent, int viewType) { 
     View v = LayoutInflater.from(parent.getContext()) 
       .inflate(R.layout.video_summ, parent, false); 
     ViewHolder viewHolder = new ViewHolder(v); 
     return viewHolder; 
    } 

    @Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     VideoItems videoList = mVideoItems.get(position); 
     holder.videoTitle.setText(videoList.getVideo_title()); 
     holder.videoBody.setText(videoList.getVideo_body()); 
    } 


    @Override 
    public int getItemCount(){ 
     //Return the number of items in the data set 
     return mVideoItems.size(); 
    } 

    class ViewHolder extends RecyclerView.ViewHolder { 
     public NetworkImageView videoImage; 
     public TextView videoTitle, videoBody; 

     public ViewHolder (View videoView) { 
      super(videoView); 
      videoTitle = (TextView) videoView.findViewById(R.id.video_title); 
      videoBody = (TextView) videoView.findViewById(R.id.video_body); 
     } 
    } 

} 

VideoItems

public class VideoItems { 
    private String video_title; 
    private String video_body; 

    public String getVideo_title() { 
     return video_title; 
    } 

    public void setVideo_title(String video_title) { 
     this.video_title = video_title; 
    } 

    public String getVideo_body() { 
     return video_body; 
    } 

    public void setVideo_body(String video_body) { 
     this.video_body = video_body; 
    } 
} 

Ich weiß nicht, ob Sie mir Tipps, wie Sie geben könnte ich es meinem RecyclerView implementieren könnte. Danke im Voraus.

Antwort

0

Sie müssen einen eigenen Listener für den Adapter implementieren, den Sie an recyclerview binden. zunächst eine Schnittstelle wie diese,

public interface OnLoadMoreListener { 
    void onLoadMore(); 
} 

In Ihrem recyclerview des Adapters setzen diese,

adapter.setOnLoadMoreListener(new OnLoadMoreListener() { 
      @Override 
      public void onLoadMore() { 
       //get your items here based on the pagination count 
      } 
     }); 

Ihre modifizierte Videoadapter

public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.ViewHolder>{ 

    private ImageLoader imageLoader; 
    private Context mContext; 

    //List of videos 
    private List<VideoItems> mVideoItems; 

    private int totalItemCount = 0,lastVisibleItem = 0,int visibleThreshold = 5; 

    private boolean loading; 
     private OnLoadMoreListener onLoadMoreListener; 

    public VideoAdapter(List<VideoItems> videoItems, Context context, RecyclerView recyclerview) { 
     super(); 

     // Getting all videos 
     this.mVideoItems = videoItems; 
     this.mContext = context; 
    LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView 
        .getLayoutManager(); 
    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { 
         @Override 
         public void onScrolled(RecyclerView recyclerView, 
               int dx, int dy) { 
          super.onScrolled(recyclerView, dx, dy); 
          totalItemCount = layoutManager.getItemCount(); 
          lastVisibleItem = layoutManager.findLastVisibleItemPosition(); 
          if (!loading 
            && totalItemCount <= (lastVisibleItem + visibleThreshold)) { 
           if (onLoadMoreListener != null) { 
            onLoadMoreListener.onLoadMore(); 
           } 
           loading = true; 
          } 
         } 
        }); 
    } 

    public void setLoaded() { 
     loading = false; 
    } 

    public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) { 
     this.onLoadMoreListener = onLoadMoreListener; 
    } 

    @Override 
    public ViewHolder onCreateViewHolder (ViewGroup parent, int viewType) { 
     View v = LayoutInflater.from(parent.getContext()) 
       .inflate(R.layout.video_summ, parent, false); 
     ViewHolder viewHolder = new ViewHolder(v); 
     return viewHolder; 
    } 

    @Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     VideoItems videoList = mVideoItems.get(position); 
     holder.videoTitle.setText(videoList.getVideo_title()); 
     holder.videoBody.setText(videoList.getVideo_body()); 
    } 


    @Override 
    public int getItemCount(){ 
     //Return the number of items in the data set 
     return mVideoItems.size(); 
    } 

    class ViewHolder extends RecyclerView.ViewHolder { 
     public NetworkImageView videoImage; 
     public TextView videoTitle, videoBody; 

     public ViewHolder (View videoView) { 
      super(videoView); 
      videoTitle = (TextView) videoView.findViewById(R.id.video_title); 
      videoBody = (TextView) videoView.findViewById(R.id.video_body); 
     } 
    } 

} 

erstellen, während der Adapter senden recyclerview Objekt

Initialisierung
adapter = new VideoAdapter(mVideoItemsList, this, recyclerView); 
012 dieses

adapter.setLoaded(); 

Hoffnung

Sobald Sie Ihren nächsten Satz von Einzelteile erhalten, erhöhen Sie Ihre Pagecount, notifyDataSetChanged() und nennen dies wird Ihnen helfen!

+0

@ Thahaseen, danke, aber das hat nicht geholfen. Es ist ähnlich dem einen der Links am Anfang meiner Frage. – Faraday

+0

@Thaheseen Die Zeile 'totalItemCount = staggeredGridLayoutManager.getItemCount();' Ist es nicht 'totalItemCount = layoutManager.getItemCount(); 'da ich einen LinearLayoutManager verwende? – Faraday

+0

Ja. Du hast recht. Ich benutzte StaggeredGridLayoutManager. das tut mir leid. aktualisierte die Antwort. Funktioniert die Lösung für Sie? – Thahaseen

Verwandte Themen