简体   繁体   中英

Android recycler view on scroll

I want to load more contents from my adapter while scrolling the recycler view.I implemented it, but its not working. my recycler view works perfectly, but I am not able to load rest of the contents from my list while scrolling. Presently there is no error in my code. but I couldn't load more items while scrolling. please help. This is my main activity.

public class Contact_school extends AppCompatActivity implements SearchView.OnQueryTextListener {
private List<Contact> Listcontact = new ArrayList<>();
Contacts_Adapter cadapter;
private RecyclerView rv;
public String GET_CONTACTS = "http://xyzx.com/Publicpages_mob/brief_school_details";
  public  Contact contact;
public String school_id;
String tag_json_obj = "json_obj_req";
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_contact_school);
    rv = (RecyclerView) findViewById(R.id.recycler_view);
    preparelist();
    cadapter = new Contacts_Adapter(Listcontact, rv);
    final LinearLayoutManager layoutManager = new     LinearLayoutManager(Contact_school.this);
    rv.setLayoutManager(layoutManager);
    rv.setItemAnimator(new DefaultItemAnimator());
    rv.setAdapter(cadapter);
    rv.setHasFixedSize(true);

   cadapter.setOnLoadMoreListener(new OnLoadMoreListener() {
       @Override
       public void onLoadMore() {

               Log.v(" KILILII ", "KITTTI");
      //add null , so the adapter will check view_type and show   progress bar at bottom
////                Listcontact.add(null);
////                cadapter.notifyItemInserted(Listcontact.size() -  1);

     //   remove progress item
////                Listcontact.remove(Listcontact.size() - 1);
////                cadapter.notifyItemRemoved(Listcontact.size());
//                //add items one by one
            int start = Listcontact.size();
            int end = start + 20;
            for (int i = start + 1; i <= end; i++) {
                Listcontact.add(contact);
                cadapter.notifyItemInserted(Listcontact.size());
            }
            cadapter.setLoaded();
                //or you can add all at once but do not forget to call mAdapter.notifyDataSetChanged();
          }
    });
}

private void preparelist() {
    final StringRequest strReq = new StringRequest(Request.Method.POST, GET_CONTACTS,                new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            try {
                JSONObject jObj = new JSONObject(response);
                Log.e("RESPONSE TEST", "" + jObj);
                JSONArray jsonArray = jObj.getJSONArray("school_details");
                Log.e("RESPONSE ARRAY", "" + jsonArray);
                    Log.d("SUCESS ", response);
                 for (int i = 0; i < jsonArray.length(); i++) {
                     JSONObject jsonobject = jsonArray.getJSONObject(i);
                         contact = new Contact();
                         contact.setAddress(jsonobject.getString("school_address"));
                         contact.setRating(jsonobject.getString("school_rating"));
         Listcontact.add(contact);
                 }
                cadapter.notifyDataSetChanged();
            } catch (JSONException e) {
                e.printStackTrace();
            }

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.e("Error", "Registration Error: " + error.getMessage());
            Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
        }
    })
    {
        @Override
        protected Map<String, String> getParams() {
            // Posting params to register url
            Map<String, String> params = new HashMap<String, String>();
            return params;
        }
    };
    AppController.getInstance().addToRequestQueue(strReq, tag_json_obj);
}

this is my adapter class

public class Contacts_Adapter extends RecyclerView.Adapter<Contacts_Adapter.MyViewHolder> {
private List<Contact> List1;

private final int VIEW_ITEM = 1;
private final int VIEW_PROG = 0;
private int visibleThreshold = 5;
private int lastVisibleItem, totalItemCount;
private boolean loading;
private OnLoadMoreListener onLoadMoreListener;
public class MyViewHolder extends RecyclerView.ViewHolder {
      public TextView text_address,text_rating;

    public MyViewHolder(View view) {
        super(view);
        text_address = (TextView)view.findViewById(R.id.textaddress);

        text_rating = (TextView)view.findViewById(R.id.textrating);

    }
}
public Contacts_Adapter(List<Contact> List1,RecyclerView recyclerView)
{
  this.List1 = List1;
    if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
        final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView
                .getLayoutManager();
        recyclerView
                .addOnScrollListener(new RecyclerView.OnScrollListener() {
                    @Override
                    public void onScrolled(RecyclerView recyclerView,
                                           int dx, int dy) {
                        super.onScrolled(recyclerView, dx, dy);
                        totalItemCount = linearLayoutManager.getItemCount();
                        lastVisibleItem = linearLayoutManager
                                .findLastVisibleItemPosition();
                        if (!loading
                                && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
                            // End has been reached
                            // Do something
                            if (onLoadMoreListener != null) {
                                onLoadMoreListener.onLoadMore();
                            }
                            loading = true;
                        }
                    }
                });
    }
}
@Override
public int getItemViewType(int position) {
    return List1.get(position) != null ? VIEW_ITEM : VIEW_PROG;
}
@Override
public Contacts_Adapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.recycler, parent, false);
    return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
    Contact c = List1.get(position);

    holder.text_rating.setText("Rating "+c.getRating());

    holder.text_address.setText(c.getAddress());

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

this is my model class

public class Contact implements Serializable {
private static final long serialVersionUID = 1L;
   private String address,rating;
 public  Contact(){
}
public  Contact (String address, String rating){
    this.address = address;
    this.rating= rating;

}

 public String getAddress(){ return address;}
public  String getRating( ){return rating;}
public void setAddress(String ad){ this.address= ad;}
public void setRating(String ad){ this.rating= ad;}
}

and I have this interface

public interface OnLoadMoreListener {
void onLoadMore();
}

please help

You don't need to track the scroll to know when to search more itens.

You can call the Volley request from the onBindViewHolder , for example:

int itemsBeforeUpdate = 10;
public void onBindViewHolder(MyViewHolder holder, final int position) {
    Contact c = List1.get(position);
    holder.text_rating.setText("Rating "+c.getRating());
    holder.text_address.setText(c.getAddress());
    if(List1.size() - position <10){
     // Do your Volley Request, add response to the list and notify the adapter that the data changed

}


}

Instead of calling OnLoadMoreListener in the following block

if (!loading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
       // End has been reached
       // Do something
       if (onLoadMoreListener != null) {
          onLoadMoreListener.onLoadMore();
       }
       loading = true;
}

Just perform your load more request in this block only. Like:

if (!loading&& totalItemCount <= (lastVisibleItem + visibleThreshold)) {
    // Load your volley request or load more request her
    loading = true;
}

and after that notify the adapter that data has been changed.

Instead of adding the values to the list in the activity class, try it by adding it to the adapter class. Say for example add an method in adapter like below.

public void addContact(Contact contact) {
list.add(contact);
notifyItemInserted(list.size());
}

And in the activity instead of this,

YOUR CODE:

cadapter.setOnLoadMoreListener(new OnLoadMoreListener() {
       @Override
       public void onLoadMore() {

               Log.v(" KILILII ", "KITTTI");
      //add null , so the adapter will check view_type and show   progress bar at bottom
////                Listcontact.add(null);
////                cadapter.notifyItemInserted(Listcontact.size() -  1);

     //   remove progress item
////                Listcontact.remove(Listcontact.size() - 1);
////                cadapter.notifyItemRemoved(Listcontact.size());
//                //add items one by one
            int start = Listcontact.size();
            int end = start + 20;
            for (int i = start + 1; i <= end; i++) {
                Listcontact.add(contact);
                cadapter.notifyItemInserted(Listcontact.size());
            }
            cadapter.setLoaded();
                //or you can add all at once but do not forget to call mAdapter.notifyDataSetChanged();
          }
    });

TRY THIS:

cadapter.setOnLoadMoreListener(new OnLoadMoreListener() {
           @Override
           public void onLoadMore() {

                   Log.v(" KILILII ", "KITTTI");

                int start = Listcontact.size();
                int end = start + 20;
                for (int i = start + 1; i <= end; i++) {
                    cadapter.addContact(contact);
                }
                cadapter.setLoaded();
              }
        });

Hope this helpful :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM