通过Json请求在recyclerview中连续滚动并使用之前的

时间:2016-03-05 16:34:10

标签: android android-recyclerview onscrolllistener

我希望通过调用页面编号增加的新JSON请求并在前面的结果中添加这些结果,在recyclerview中实现无限滚动。第一个请求显示20个结果,但仍有200多个结果显示。如何在'TopratedFragment.java'中使用onLoadMore()函数进行无限滚动。请帮助代码

  

TopratedFragment.java

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.JsonObjectRequest;
import com.example.mitab.mentor.Movies.Pages.L;
import com.example.mitab.mentor.Movies.Pages.MyApplication;
import com.example.mitab.mentor.Movies.Pages.VolleySingleton;
import com.example.mitab.mentor.Movies.Pages.movie;
import com.example.mitab.mentor.R;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import android.os.Handler;

import static com.example.mitab.mentor.Movies.Pages.Keys.EndpointToprated.*;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link TopratedFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class TopratedFragment extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";
    public static final String Top_rated="http://api.themoviedb.org/3/movie/top_rated";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;
    protected Handler handler;
    private VolleySingleton volleySingleton;
    private ImageLoader imageLoader;
    int page=1;
    private RequestQueue requestQueue;
    private ArrayList<movie> listMovies=new ArrayList<>();
    private ArrayList<movie> newlistMovies=new ArrayList<>();
    private SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
    private RecyclerView listMovieHits;
    private AdapterToprated adapterToprated;
    boolean loadingMore = false;
    private int lastVisibleItemId=0;


    public TopratedFragment() {
        // Required empty public constructor
    }

    // TODO: Rename and change types and number of parameters
    public static TopratedFragment newInstance(String param1, String param2) {
        TopratedFragment fragment = new TopratedFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }

        volleySingleton= VolleySingleton.getsInstance();
        requestQueue=volleySingleton.getRequestQueue();

        sendJsonRequest();
    }

    private void sendJsonRequest(){
        JsonObjectRequest request=new JsonObjectRequest(Request.Method.GET, getRequestUrl(page), (String)null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                listMovies=parseJSONResponse(response);
                adapterToprated.setMovieList(listMovies);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });
        requestQueue.add(request);
    }

    private ArrayList<movie> parseJSONResponse(JSONObject response){
        ArrayList<movie> listMovies=new ArrayList<>();
        if (response==null || response.length()>0){



            try {
                JSONArray arrayMovies=response.getJSONArray(KEY_MOVIES);
                for (int i=0;i<arrayMovies.length();i++){

                    long id=-1;
                    String title="NA";
                    String poster="NA";
                    String release="NA";
                    String overview="NA";
                    String vote="NA";
                    String votecount="NA";

                    JSONObject currentMovie=arrayMovies.getJSONObject(i);

                    //get the id of current movie
                    if (currentMovie.has(KEY_ID)&& !currentMovie.isNull(KEY_ID)){
                        id=currentMovie.getLong(KEY_ID);
                    }

                    if (currentMovie.has(KEY_TITLE)&& !currentMovie.isNull(KEY_TITLE)){
                        title=currentMovie.getString(KEY_TITLE);
                    }

                    if (currentMovie.has(KEY_POSTER_PATH)&& !currentMovie.isNull(KEY_POSTER_PATH)){
                        poster=currentMovie.getString(KEY_POSTER_PATH);
                    }

                    if (currentMovie.has(KEY_RELEASE_DATE)&& !currentMovie.isNull(KEY_RELEASE_DATE)){
                        release=currentMovie.getString(KEY_RELEASE_DATE);
                    }

                    if (currentMovie.has(KEY_OVERVIEW)&& !currentMovie.isNull(KEY_OVERVIEW)){
                        overview=currentMovie.getString(KEY_OVERVIEW);
                    }

                    if (currentMovie.has(KEY_AVERAGE_VOTE)&& !currentMovie.isNull(KEY_AVERAGE_VOTE)){
                        vote=currentMovie.getString(KEY_AVERAGE_VOTE);
                    }

                    if (currentMovie.has(KEY_VOTE_COUNT)&& !currentMovie.isNull(KEY_VOTE_COUNT)){
                        votecount=currentMovie.getString(KEY_VOTE_COUNT);
                    }







                    JSONArray genre=currentMovie.getJSONArray(KEY_GENRE_IDS);

                    if (currentMovie.has(KEY_GENRE_IDS)&& !currentMovie.isNull(KEY_GENRE_IDS)){
                        for (int j=0;j<genre.length();j++){
                            try {
                                String itemInArray=genre.getString(j);

                            }
                            catch (JSONException e){

                            }
                        }
                    }


                    movie movie=new movie();
                    movie.setId(id);
                    movie.setTitle(title);
                    movie.setOverview(overview);
                    movie.setAveragevote(vote);
                    Date date=null;
                    try {
                        date=dateFormat.parse(release);
                    }
                    catch (ParseException e){

                    }

                    movie.setReleasedate(date);
                    movie.setImage(poster);
                    movie.setVotecount(votecount);

                    if (id!=-1 && !title.equals("NA"))
                    {
                        listMovies.add(movie);
                    }


                }



            }
            catch (JSONException e){

            }
        }
        return listMovies;
    }

    public static String getRequestUrl(int page){
        return Top_rated +"?api_key="+ MyApplication.API_KEY + "&page="+page;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.fragment_toprated, container, false);

        final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
        handler=new Handler();
        listMovieHits=(RecyclerView) view.findViewById(R.id.listMovieHits);
        listMovieHits.setLayoutManager(linearLayoutManager);

        adapterToprated=new AdapterToprated(getActivity());
        listMovieHits.setAdapter(adapterToprated);
        //sendJsonRequest();
        // Add the scroll listener
        listMovieHits.addOnScrollListener(new EndlessRecyclerViewScrollListener(linearLayoutManager) {
            @Override
            public void onLoadMore(int page, int totalItemsCount) {
                loadingMore=true;
                sendJsonRequest();
                int curlsize=adapterToprated.getItemCount();
                listMovies.addAll(newlistMovies);
                adapterToprated.notifyItemRangeChanged(curlsize,listMovies.size()-2);
            }
        });
        // Inflate the layout for this fragment
        return view;
    }



}
  

AdapterToprated.java

import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.example.mitab.mentor.MainActivity;
import com.example.mitab.mentor.Movies.Pages.L;
import com.example.mitab.mentor.Movies.Pages.VolleySingleton;
import com.example.mitab.mentor.Movies.Pages.movie;
import com.example.mitab.mentor.R;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;


public class AdapterToprated extends RecyclerView.Adapter<AdapterToprated.ViewHolderToprated> {

    private LayoutInflater layoutInflater;
    private VolleySingleton volleySingleton;
    private ImageLoader imageLoader;
    private ArrayList<movie> listMovies=new ArrayList<movie>();
    private SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
    private RecyclerView.OnItemTouchListener onItemTouchListener;
    Context context;



    public AdapterToprated(Context context){
        layoutInflater=LayoutInflater.from(context);
        volleySingleton=VolleySingleton.getsInstance();
        imageLoader=volleySingleton.getImageLoader();
        this.context = context;
    }

    public void setMovieList(ArrayList<movie> listMovies){
        this.listMovies=listMovies;
        notifyItemRangeChanged(0, listMovies.size());
    }
    @Override
    public ViewHolderToprated onCreateViewHolder(ViewGroup parent, int viewType) {
        View view=layoutInflater.inflate(R.layout.individual_toprated, parent, false);
        ViewHolderToprated viewHolderToprated=new ViewHolderToprated(view);
        return viewHolderToprated;
    }

    @Override
    public void onBindViewHolder(final ViewHolderToprated holder, int position) {
        final movie currentMovie=listMovies.get(position);
        holder.movieTitle.setText(currentMovie.getTitle());
        Date movieReleaseDate=currentMovie.getReleasedate();
        if (movieReleaseDate!=null){
            String formattedDate=dateFormat.format(movieReleaseDate);
            holder.movieReleaseDate.setText(formattedDate);
        }else{
            holder.movieReleaseDate.setText("NA");
        }

        holder.movieRating.setText(currentMovie.getAveragevote());
        String urlThumnail=currentMovie.getImage();
        if (!urlThumnail.equals("NA")){
            imageLoader.get(urlThumnail, new ImageLoader.ImageListener() {
                @Override
                public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
                    holder.movieThumbnail.setImageBitmap(response.getBitmap());
                }

                @Override
                public void onErrorResponse(VolleyError error) {

                }
            });
        }
        holder.lnrLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(context,Intentpass.class);
                Bundle extras=new Bundle();
                extras.putString("Title","currentMovie.getTitle()");
                extras.putString("Date","formattedDate");
                extras.putString("Rating","currentMovie.getAveragevote()");
                intent.putExtras(extras);
                context.startActivity(intent);
                //intent.putExtra("details",currentMovie.getTitle());
                //context.startActivity(intent);

            }
        });


    }

    @Override
    public int getItemCount() {
        return listMovies.size();
    }

    static class ViewHolderToprated extends RecyclerView.ViewHolder{

        private ImageView movieThumbnail;
        private TextView movieTitle;
        private TextView movieReleaseDate;
        private TextView movieRating;
        private RelativeLayout lnrLayout;

        public ViewHolderToprated(View itemView) {
            super(itemView);
            movieThumbnail=(ImageView) itemView.findViewById(R.id.movieThumbnail);
            movieTitle=(TextView) itemView.findViewById(R.id.movieTitle);
            movieReleaseDate=(TextView) itemView.findViewById(R.id.movieReleaseDate);
            movieRating=(TextView) itemView.findViewById(R.id.movieRating);
            lnrLayout=(RelativeLayout)itemView.findViewById(R.id.lnLayout);
        }
    }
}
  

EndlessRecyclerViewScrollListener.java

import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;

public abstract class EndlessRecyclerViewScrollListener extends RecyclerView.OnScrollListener {
    // The minimum amount of items to have below your current scroll position
    // before loading more.
    private int visibleThreshold = 5;
    // The current offset index of data you have loaded
    private int currentPage = 0;
    // The total number of items in the dataset after the last load
    private int previousTotalItemCount = 0;
    // True if we are still waiting for the last set of data to load.
    private boolean loading = true;
    // Sets the starting page index
    private int startingPageIndex = 0;

    RecyclerView.LayoutManager mLayoutManager;

    public EndlessRecyclerViewScrollListener(LinearLayoutManager layoutManager) {
        this.mLayoutManager = layoutManager;
    }

    public EndlessRecyclerViewScrollListener(GridLayoutManager layoutManager) {
        this.mLayoutManager = layoutManager;
        visibleThreshold = visibleThreshold * layoutManager.getSpanCount();
    }

    public EndlessRecyclerViewScrollListener(StaggeredGridLayoutManager layoutManager) {
        this.mLayoutManager = layoutManager;
        visibleThreshold = visibleThreshold * layoutManager.getSpanCount();
    }

    public int getLastVisibleItem(int[] lastVisibleItemPositions) {
        int maxSize = 0;
        for (int i = 0; i < lastVisibleItemPositions.length; i++) {
            if (i == 0) {
                maxSize = lastVisibleItemPositions[i];
            }
            else if (lastVisibleItemPositions[i] > maxSize) {
                maxSize = lastVisibleItemPositions[i];
            }
        }
        return maxSize;
    }

    // This happens many times a second during a scroll, so be wary of the code you place here.
    // We are given a few useful parameters to help us work out if we need to load some more data,
    // but first we check if we are waiting for the previous load to finish.
    @Override
    public void onScrolled(RecyclerView view, int dx, int dy) {
        int lastVisibleItemPosition = 0;
        int totalItemCount = mLayoutManager.getItemCount();

        if (mLayoutManager instanceof StaggeredGridLayoutManager) {
            int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(null);
            // get maximum element within the list
            lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions);
        } else if (mLayoutManager instanceof LinearLayoutManager) {
            lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition();
        } else if (mLayoutManager instanceof GridLayoutManager) {
            lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition();
        }

        // If the total item count is zero and the previous isn't, assume the
        // list is invalidated and should be reset back to initial state
        if (totalItemCount < previousTotalItemCount) {
            this.currentPage = this.startingPageIndex;
            this.previousTotalItemCount = totalItemCount;
            if (totalItemCount == 0) {
                this.loading = true;
            }
        }
        // If it’s still loading, we check to see if the dataset count has
        // changed, if so we conclude it has finished loading and update the current page
        // number and total item count.
        if (loading && (totalItemCount > previousTotalItemCount)) {
            loading = false;
            previousTotalItemCount = totalItemCount;
        }

        // If it isn’t currently loading, we check to see if we have breached
        // the visibleThreshold and need to reload more data.
        // If we do need to reload some more data, we execute onLoadMore to fetch the data.
        // threshold should reflect how many total columns there are too
        if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) {
            currentPage++;
            onLoadMore(currentPage, totalItemCount);
            loading = true;
        }
    }

    // Defines the process for actually loading more data based on page
    public abstract void onLoadMore(int page, int totalItemsCount);

}

1 个答案:

答案 0 :(得分:2)

您只需将新数据添加到列表电影的最后位置,一切都会正常工作。为此 -

创建一个新列表,例如 ArrayList&lt; movie&gt; newListMovies 并将更新后的数据添加到其中。现在将 newListMovies 添加到 listMovies 并通知适配器。就像下面一样 -

  ArrayList<movie> newListMovies = new ArrayList<>();

  // your code..

  listMovieHits.addOnScrollListener(new EndlessRecyclerViewScrollListener(linearLayoutManager) {
        @Override
        public void onLoadMore(int page, int totalItemsCount) {
            loadingMore=true;
            sendJsonRequest();

            int currentSize = adapter.getItemCount();
            listMovies.addAll(newListMovies);
            adapter.notifyItemRangeInserted(currentSize, listMovies.size() - 2);
        }
    });

希望它会有所帮助。