无尽的recyclerview加载更多滚动到列表的开始

时间:2016-02-23 05:03:23

标签: android android-recyclerview infinite-scroll

我的应用程序中有更多功能,但当我到达列表末尾时,会加载新项目,但列表会自动滚动到列表的开头。

这是onload函数:

         recyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(mLayoutManager) {
            @Override
            public void onLoadMore(int current_page, int position) {
                // do something...
                Log.d("Yaeye!", "HElloyoyo");
                SuperHeroes superHero = listSuperHeroes.get(position);

                Log.d("we want url", superHero.getImageUrl());
                imgoffset = superHero.getImageUrl();
                // Do something
                getData(0);

            }
        });

以下是从服务器收到的数据的解析:

           JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(url,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        //Dismissing progress dialog
                        // loading.dismiss();

                        //calling method to parse json array
                        parseData(response);

                            adapter.notifyDataSetChanged();



                    }

                },

                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);


    }
    public int z;
    //This method will parse json data
    private int parseData(JSONArray array){
        for(int i = 0; i<array.length(); i++) {
            SuperHeroes superHero = new SuperHeroes();
            CardAdapter car = new CardAdapter();
            JSONObject json = null;
            try {
                json = array.getJSONObject(i);
                superHero.setImageUrl(json.getString(Config.TAG_IMAGE_URL));
                superHero.setProUrl(json.getString("pro_pic"));
                Img =json.getString(Config.TAG_IMAGE_URL);
                superHero.setName(json.getString(Config.TAG_NAME));
                superHero.setRank(json.getInt(Config.TAG_RANK));
                superHero.setstat(false);

                Log.d("test",Img);
                car.setImageUrl(Img);


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

             adapter.notifyItemInserted(listSuperHeroes.size());
                listSuperHeroes.add(superHero);

             //   adapter.notifyDataSetChanged();
                loading=false;
      }

EndlessRecyclerOnScrollListener来自here

package com.example.tatson.bila;



        import android.app.ProgressDialog;
        import android.content.ContentValues;
        import android.content.Context;
        import android.content.SharedPreferences;
        import android.media.Image;
        import android.os.AsyncTask;
        import android.os.Bundle;
        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 android.widget.Button;
        import android.widget.ImageButton;
        import android.widget.ImageView;
        import android.widget.TextView;
        import android.widget.Toast;
        import com.example.tatson.bila.Register;

        import com.android.volley.toolbox.ImageLoader;
        import com.android.volley.toolbox.NetworkImageView;

        import org.json.JSONException;
        import org.json.JSONObject;
        import org.w3c.dom.Text;

        import java.io.BufferedReader;
        import java.io.IOException;
        import java.io.InputStreamReader;
        import java.io.OutputStream;
        import java.io.OutputStreamWriter;
        import java.io.UnsupportedEncodingException;
        import java.net.HttpURLConnection;
        import java.net.URL;
        import java.net.URLEncoder;
        import java.util.ArrayList;
        import java.util.HashMap;
        import java.util.List;
        import java.util.Map;

        import javax.net.ssl.HttpsURLConnection;

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


    private String imageUrl;
    private ImageLoader imageLoader,imageLoader1;
    private Context context;
    String Load;
private static ClickListener c;
    public static final String uu = "uu";
    String number;

    public static final String UserNum = "UserNum";
    SharedPreferences sharedPref;

    private String[] pos;
    private int visibleThreshold = 5;
    private int lastVisibleItem, totalItemCount;
    private boolean loading;
    private OnLoadMoreListener onLoadMoreListener;
    // JSON parser class
    JSONParser jsonParser = new JSONParser();
    String url,imgoffset;
    //testing from a real server:
    private static final String LIKE_URL = "**";

    //ids
    private static final String TAG_SUCCESS = "success";
    private static final String TAG_MESSAGE = "message";
    List<SuperHeroes> superHeroes1;
    //List of superHeroes

    List<SuperHeroes> superHeroes;
    private RecyclerView recyclerView;


    public CardAdapter() {
    }

    public CardAdapter(List<SuperHeroes> superHeroes, Context context) {
        super();
        //Getting all the superheroes
        this.superHeroes = superHeroes;
        superHeroes1= superHeroes;
        this.context = context;
        sharedPref  =context.getSharedPreferences(UserNum, 0);
        number =  sharedPref.getString(uu, "");

    }


    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }

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



    }


    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {

        SuperHeroes superHero = superHeroes.get(position);
       Log.d("position", String.valueOf(position));
        Log.d("url", superHero.getImageUrl());
        imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader();
        imageLoader.get(superHero.getImageUrl(), ImageLoader.getImageListener(holder.imageView, R.mipmap.ic_launcher, android.R.drawable.ic_dialog_alert));
        imageLoader1 = CustomVolleyRequest.getInstance(context).getImageLoader();
        imageLoader1.get(superHero.getProurl(), ImageLoader.getImageListener(holder.thumbNail, R.mipmap.ic_launcher, android.R.drawable.ic_dialog_alert));

        Log.d("i am ob", "ob");
        holder.imageView.setImageUrl(superHero.getImageUrl(), imageLoader);
        holder.thumbNail.setImageUrl(superHero.getProurl(), imageLoader1);
        holder.textViewName.setText(superHero.getName());
        holder.textViewRank.setText(String.valueOf(superHero.getRank()));

      if(superHero.getstat())
     {
          Log.d("i am g","g");
         Log.d("i am value", String.valueOf(superHero.getstat()));
            holder.like.setImageResource(R.drawable.plike);
        }
       else
       {
          Log.d("i am p","p");
            holder.like.setImageResource(R.drawable.glike);
        }



        // holder.textViewPowers.setText(powers);
        holder.like.setOnClickListener(new View.OnClickListener(){

@Override
            public void onClick(View v) {
                Log.d("i m in like","i m in like");
            if(dudo!=null) {
                Log.d("i m in like1", "i m in like1");
                dudo.onlike(v, position);


            }}        });


    }

public void refresh(List<SuperHeroes> superHeroes){
    Log.d("Refresh","Refresh is called ");
    this.superHeroes=superHeroes;
  //  notifyDataSetChanged();
}

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






        public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
            public NetworkImageView imageView;
          public CircularNetworkImageView thumbNail;
            public TextView textViewName;
            public TextView textViewuserName;
            public TextView textViewRank;
            public ImageButton like;
        public ViewHolder(View itemView) {
            super(itemView);
            imageView = (NetworkImageView) itemView.findViewById(R.id.imageViewHero);
            textViewName = (TextView) itemView.findViewById(R.id.username_row);
            //textViewuserName = (TextView) itemView.findViewById(R.id.username_row);
            textViewRank = (TextView) itemView.findViewById(R.id.textViewRank);
            thumbNail = (CircularNetworkImageView) itemView.findViewById(R.id.thumbnail);
            like = (ImageButton) itemView.findViewById(R.id.button_like);
         //   itemView.setOnClickListener( this);




        }


        @Override
        public void onClick(View v) {
            if (dudo != null) {
                Log.d("i m in like1", "i m in like1");
                dudo.onlike(v, 2);
            }
        }
    }


    class LikeIt extends AsyncTask<String, String, String> {

        /**
         * Before starting background thread Show Progress Dialog
         */
        boolean failure = false;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }

        @Override
        protected String doInBackground(String... args) {
            // TODO Auto-generated method stub
            // Check for success tag

             int success;

            String Imgurl = Load;
            Log.d("request!", number);

          //  try {
                // Building Parameters
                HashMap<String, String> Params = new HashMap<String, String>();
                Params.put("Imgurl", Imgurl);
           Params.put("user", number);


                Log.d("request!", "starting");


                String encodedStr = getEncodedData(Params);

                //Will be used if we want to read some data from server
                BufferedReader reader = null;

                //Connection Handling
                try {
                    //Converting address String to URL
                    URL url = new URL(LIKE_URL);
                    //Opening the connection (Not setting or using CONNECTION_TIMEOUT)
                    HttpURLConnection con = (HttpURLConnection) url.openConnection();

                    //Post Method
                    con.setRequestMethod("POST");
                    //To enable inputting values using POST method
                    //(Basically, after this we can write the dataToSend to the body of POST method)
                    con.setDoOutput(true);
                    OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream());
                    //Writing dataToSend to outputstreamwriter
                    writer.write(encodedStr);
                    //Sending the data to the server - This much is enough to send data to server
                    //But to read the response of the server, you will have to implement the procedure below
                    writer.flush();

                    //Data Read Procedure - Basically reading the data comming line by line
                    StringBuilder sb = new StringBuilder();
                    reader = new BufferedReader(new InputStreamReader(con.getInputStream()));

                    String line;
                    while((line = reader.readLine()) != null) { //Read till there is something available
                        sb.append(line + "\n");     //Reading and saving line by line - not all at once
                    }
                    line = sb.toString();           //Saving complete data received in string, you can do it differently

                    //Just check to the values received in Logcat
                    Log.i("custom_check","The values :");
                    Log.i("custom_check", line);

                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if(reader != null) {
                        try {
                            reader.close();     //Closing the
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }

                //Same return null, but if you want to return the read string (stored in line)
                //then change the parameters of AsyncTask and return that type, by converting
                //the string - to say JSON or user in your case
                return null;
            }

        }
    private String getEncodedData(Map<String,String> data) {
        StringBuilder sb = new StringBuilder();
        for(String key : data.keySet()) {
            String value = null;
            try {
                value = URLEncoder.encode(data.get(key), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            if(sb.length()>0)
                sb.append("&");

            sb.append(key + "=" + value);
        }
        return sb.toString();
    }

        /**
         * After completing background task Dismiss the progress dialog
         **/
        protected void onPostExecute() {
            // dismiss the dialog once product deleted

            }


private  static ClickListener dudo ;
  public interface ClickListener{
       void onlike(View v,int pos);



    }
    public void setClickListener(ClickListener dudo){
        this.dudo=dudo;
        Log.d("i m in interface","i m in interface");
    }
}

3 个答案:

答案 0 :(得分:0)

修改你的for循环并再试一次

for(int i = 0; i<array.length(); i++) {
    SuperHeroes superHero = new SuperHeroes();
    CardAdapter car = new CardAdapter();
    JSONObject json = null;
    try {
        json = array.getJSONObject(i);  
        superHero.setImageUrl(json.getString(Config.TAG_IMAGE_URL));
        superHero.setProUrl(json.getString("pro_pic"));
        Img =json.getString(Config.TAG_IMAGE_URL);
        superHero.setName(json.getString(Config.TAG_NAME));
        superHero.setRank(json.getInt(Config.TAG_RANK));
        superHero.setstat(false);

        Log.d("test",Img);
        car.setImageUrl(Img);
    } catch (JSONException e) {
        e.printStackTrace();
    }    
    listSuperHeroes.add(superHero);
}
loading=false;
adapter.notifyDataSetChanged();
//adapter.notifyItemInserted(listSuperHeroes.size());

我的猜测是,每次在 for循环中添加项目时,您都会刷新,这可能是您的问题。

答案 1 :(得分:0)

private int parseData(JSONArray array){
  //temporary List to store all the new data from the json
  List<SuperHeroes> tempList=new ArrayList<>();
  //get start position to use later
  int startPos=listSuperHeroes.size()-1;
    for(int i = 0; i<array.length(); i++) {
        SuperHeroes superHero = new SuperHeroes();
        CardAdapter car = new CardAdapter();
        JSONObject json = null;
        try {
            json = array.getJSONObject(i);
            superHero.setImageUrl(json.getString(Config.TAG_IMAGE_URL));
            superHero.setProUrl(json.getString("pro_pic"));
            Img =json.getString(Config.TAG_IMAGE_URL);
            superHero.setName(json.getString(Config.TAG_NAME));
            superHero.setRank(json.getInt(Config.TAG_RANK));
            superHero.setstat(false);

            Log.d("test",Img);
            car.setImageUrl(Img);


        } catch (JSONException e) {
            e.printStackTrace();
            //You do not want to add the item incase there is a json exception
            continue;
        }


            tempList.add(superHero);

         //   adapter.notifyDataSetChanged();
            loading=false;
  }
     listSuperHeroes.addAll(tempList)
     adapter.notifyItemRangeInserted(startPos,tempList.size());
}

您想要添加所有项目并致电notifyDatasetChanged()一次。如果您在每次添加时都致电notifyDatasetChanged(),您很可能会很快遇到Inconsistency Detected例外。

RecyclerView有几种辅助方法来通知数据集中的更改。 notifyDatasetChanged()是刷新整个数据集的那个,在你的场景中这将是一种过度杀伤。

考虑使用notifyItemRangeInserted等其他方法,这些方法会将项目添加到列表底部。 这有两个主要优点   - 您的列表不会跳转到添加数据的位置   - RecyclerView自动动画添加(可以覆盖)

如果您的职位/项目数不正确,您将面临Inconsistency Detected错误的问题。

在这种情况下,您可以使用notifyDatasetChanged()

答案 2 :(得分:0)

试试这个,

private int previousTotal = 0;
private boolean loading = true;
private int visibleThreshold = 5;
int firstVisibleItem, visibleItemCount, totalItemCount;

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
    super.onScrolled(recyclerView, dx, dy);

    visibleItemCount = mRecyclerView.getChildCount();
    totalItemCount = mLayoutManager.getItemCount();
    firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();

    if (loading) {
        if (totalItemCount > previousTotal) {
            loading = false;
            previousTotal = totalItemCount;
        }
    }
    if (!loading && (totalItemCount - visibleItemCount) 
        <= (firstVisibleItem + visibleThreshold)) {
        // End has been reached

        Log.i("Yaeye!", "end called");

        // Do something

        loading = true;
    }
}
});

LinearLayoutManager mLayoutManager;
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);