Main activty.java
i am using volley library.
here i am trying to do is load 10 images on Card views until user reach at the end
public class MainActivity extends ActionBarActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
String loginURL="http://*****o.comli.com/rimgid.php";
RequestQueue requestQueue;
String[] title=null,url=null;
int i=0;
Activity activity= MainActivity.this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
requestQueue = Volley.newRequestQueue(this);
//output = (TextView) findViewById(R.id.hi);
JsonObjectRequest jor = new JsonObjectRequest(Request.Method.GET, loginURL,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try{
JSONArray ja = response.getJSONArray("hi");//parsing id and image url
title=new String[ja.length()];
url=new String[ja.length()];
for(int i=0; i < ja.length(); i++){
JSONObject jsonObject = ja.getJSONObject(i);
// int id = Integer.parseInt(jsonObject.optString("id").toString());
url[i] ="http://developer.andrinfo.comli.com/img/"+ jsonObject.getInt("id")+".jpg";
title[i] = jsonObject.getString("name");
}
mAdapter = new MyRecyclerViewAdapter(activity,getDataSet(url,title,ja.length()));
mRecyclerView.setAdapter(mAdapter);
// Toast.makeText(getApplicationContext(),url[2],Toast.LENGTH_SHORT).show();
//output.setText(data);
}catch(JSONException e){e.printStackTrace();}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Volley",error.toString());
}
}
);
requestQueue.add(jor);
//requestQueue.start();
// Code to Add an item with default animation
//((MyRecyclerViewAdapter) mAdapter).addItem(obj, index);
// Code to remove an item with default animation
//((MyRecyclerViewAdapter) mAdapter).deleteItem(index);
}
private ArrayList<DataObject> getDataSet(String[] images,String[] headlines,int size) {
// String[] images = getResources().getStringArray(R.array.images_array);
//String[] headlines = getResources().getStringArray(R.array.headline_array);
ArrayList results = new ArrayList<DataObject>();
for (int index = 0; index < size; index++) {
DataObject obj = new DataObject(headlines[index],
"Secondary " + index);
obj.setUrl(images[index]);
//obj.setHeadline(headlines[index]);
results.add(index, obj);
}
return results;
}
}
my adapter class
public class MyRecyclerViewAdapter extends RecyclerView
.Adapter<MyRecyclerViewAdapter
.DataObjectHolder> {
private static String LOG_TAG = "MyRecyclerViewAdapter";
private ArrayList<DataObject> mDataset;
private static MyClickListener myClickListener;
private String headline;
private String reporterName;
private String date;
private String url;
private Activity activityContext;
public static class DataObjectHolder extends RecyclerView.ViewHolder
{
TextView label;
TextView dateTime;
ImageView imageView;
public DataObjectHolder(View itemView) {
super(itemView);
label = (TextView) itemView.findViewById(R.id.textView);
dateTime = (TextView) itemView.findViewById(R.id.textView2);
imageView=(ImageView)itemView.findViewById(R.id.imageView);
Log.i(LOG_TAG, "Adding Listener");
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
}
public MyRecyclerViewAdapter(Activity context,ArrayList<DataObject> myDataset) {
mDataset = myDataset;
activityContext=context;
}
#Override
public DataObjectHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cardview, parent, false);
DataObjectHolder dataObjectHolder = new DataObjectHolder(view);
return dataObjectHolder;
}
#Override
public void onBindViewHolder(DataObjectHolder holder, int position) {
Context context=null;
holder.label.setText(mDataset.get(position).getmText1());
holder.dateTime.setText(mDataset.get(position).getmText2());
Drawable placeholder = holder.imageView.getContext().getResources().getDrawable(R.drawable.placeholder);
holder.imageView.setImageDrawable(placeholder);
//new ImageDownloaderTask(holder.imageView).execute(mDataset.get(position).getUrl());
Picasso.with(activityContext)
.load(mDataset.get(position).getUrl())
.placeholder(R.drawable.placeholder)
.into(holder.imageView);
}
public void addItem(DataObject dataObj, int index) {
mDataset.add(index, dataObj);
notifyItemInserted(index);
}
public void deleteItem(int index) {
mDataset.remove(index);
notifyItemRemoved(index);
}
#Override
public int getItemCount() {
return mDataset.size();
}
public interface MyClickListener {
public void onItemClick(int position, View v);
}
}
please help me to do this.
I want to use the scroll listener with the main activity..
I use this class to implement endless scrolling behaviour on RecyclerViews
public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener {
public static String TAG = EndlessRecyclerOnScrollListener.class.getSimpleName();
private int previousTotal = 0; // The total number of items in the dataset after the last load
private boolean loading = true; // True if we are still waiting for the last set of data to load.
private int visibleThreshold = 5; // The minimum amount of items to have below your current scroll position before loading more.
int firstVisibleItem, visibleItemCount, totalItemCount;
private int current_page = 1;
private LinearLayoutManager mLinearLayoutManager;
public EndlessRecyclerOnScrollListener(LinearLayoutManager linearLayoutManager) {
this.mLinearLayoutManager = linearLayoutManager;
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = recyclerView.getChildCount();
totalItemCount = mLinearLayoutManager.getItemCount();
firstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount - visibleItemCount)
<= (firstVisibleItem + visibleThreshold)) {
// End has been reached
// Do something
current_page++;
onLoadMore(current_page);
loading = true;
}
}
public abstract void onLoadMore(int current_page);
}
Use it like this:
mRecyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(layoutManager) {
#Override
public void onLoadMore(int current_page) {
//call server
getRestaurantReviews(current_page);
}
});
Related
I am implementing pagination in recyclerview on scroll. I am fetching data from JSON API. Below is the code of Fragment Class. 1st page is loading successfully in recyclerview, but when I scroll to bottom 2nd page is not loading and throws the following error:
java.lang.IndexOutOfBoundsException: Index: 10, Size: 10
This is my Fragment Class:
public class LeadsFragment extends Fragment {
RecyclerView recyclerView;
LeadsAdapter leadsAdapter;
List<LeadModel> rowsArrayList = new ArrayList<>();
private LinearLayoutManager layoutManager;
Toolbar toolbar;
private int page = 1;
private int totalItemCount;
private int firstVisibleItem;
private int visibleItemCount;
private int previousTotal;
private boolean isLoad=true;
String url;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_leads, container, false);
toolbar = view.findViewById(R.id.toolbar);
( (AppCompatActivity) getActivity() ).setSupportActionBar(toolbar);
( (AppCompatActivity) getActivity() ).getSupportActionBar().setTitle("");
url = "myurl?page="+page;
recyclerView = view.findViewById(R.id.recyclerview);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
leadsAdapter = new LeadsAdapter(getContext(), rowsArrayList, recyclerView);
recyclerView.setAdapter(leadsAdapter);
getAPIData();
pagination();
return view;
}
private void getAPIData() {
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
LeadModel leadModelList = gson.fromJson(response, LeadModel.class);
for (int i = 0; i < leadModelList.getData().size(); i++) {
rowsArrayList.add(leadModelList);
}
leadsAdapter.setItems(rowsArrayList);
leadsAdapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getContext(), error.toString(), Toast.LENGTH_SHORT).show();
}
});
RequestQueue queue = Volley.newRequestQueue(getContext());
queue.add(stringRequest);
}
private void pagination() {
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(#NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) {
visibleItemCount = layoutManager.getChildCount();
totalItemCount = layoutManager.getItemCount();
firstVisibleItem = layoutManager.findFirstVisibleItemPosition();
Log.e("visibleItemCount", "." + visibleItemCount);
Log.e("totalItemCount", "." + totalItemCount);
Log.e("firstVisibleItem", "." + firstVisibleItem);
if (isLoad) {
if (totalItemCount > previousTotal) {
previousTotal = totalItemCount;
page++;
isLoad = false;
Log.e("previousTotal", "." + previousTotal);
Log.e("Pageeeee", "." + page);
}
}
if (!isLoad && ( firstVisibleItem + visibleItemCount ) >= totalItemCount) {
Log.e("Checking", "." + page);
getAPIData();
isLoad = true;
}
}
}
});
}
}
My Adapter Class:
public class LeadsAdapter extends RecyclerView.Adapter<LeadsAdapter.ViewHolder> {
Context context;
List<LeadModel> leadsModelList;
LeadsMeta leadsMetaList;
RecyclerView recyclerView;
final View.OnClickListener onClickListener = new MyOnClickListener();
public LeadsAdapter(Context context, List<LeadModel> leadsModelList, RecyclerView recyclerView) {
this.context = context;
this.leadsModelList = leadsModelList;
this.recyclerView = recyclerView;
}
public void setItems(List<LeadModel> leadsModelList) {
this.leadsModelList= new ArrayList<>(leadsModelList);
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView name, topic, sub_topic, city, credits, quotes;
public ViewHolder(#NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.tvName);
topic = itemView.findViewById(R.id.tvTopic);
sub_topic = itemView.findViewById(R.id.tvSubTopic);
city = itemView.findViewById(R.id.tvLocation);
credits = itemView.findViewById(R.id.tvCredits);
quotes = itemView.findViewById(R.id.tvQuotes);
}
}
#NonNull
#Override
public LeadsAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.lead_card, viewGroup, false);
view.setOnClickListener(onClickListener);
LeadsAdapter.ViewHolder viewHolder = new LeadsAdapter.ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull LeadsAdapter.ViewHolder viewHolder, int position) {
LeadModel leadsModel = leadsModelList.get(position);
viewHolder.name.setText(leadsModel.getData().get(position).getName());
}
#Override
public int getItemCount() {
return leadsModelList.size();
}
}
Whenever calling getApi method sends new response and adding data again to the list, but that list not sent to adapter to update new list.
Instead of like this
leadsAdapter = new LeadsAdapter(getContext(), rowsArrayList, recyclerView);
Create a method in adapter with list as a parameter and pass the arraylist to method and notify when new data response.
I have a problem with Recyclerview load more items. First fetch data work perfectly. Added onScrolled method, added offset to request. try to display 10 records at a time (increase offset by 10 in each request and set limit on 10 by starting with offset 0 and increasing it each time when bottom is reached. Every request should return next 10 items). Please check my below code.
PersonUtils.java
public class PersonUtils {
private String personFirstName;
private String jobProfile;
public String getPersonFirstName() {
return personFirstName;
}
public void setPersonFirstName(String personFirstName) {
this.personFirstName = personFirstName;
}
public String getJobProfile() {
return jobProfile;
}
public void setJobProfile(String jobProfile) {
this.jobProfile = jobProfile;
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
RecyclerView.Adapter mAdapter;
RecyclerView.LayoutManager layoutManager;
List<PersonUtils> personUtilsList;
RequestQueue rq;
String request_url = "https://next.json-generator.com/api/json/get/Vkg6e6Vcu";
String url = "https://.../api/json/offset=";
static int total = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rq = Volley.newRequestQueue(this);
recyclerView = (RecyclerView) findViewById(R.id.recycleViewContainer);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
personUtilsList = new ArrayList<>();
sendRequest(request_url);
// sendRequest(url, 0);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
System.out.print("test");
if(dx>0){
}
if(dy>0){
total = total+10;
System.out.print("testing");
// sendRequest(url, total);
sendRequest(request_url);
}
}
});
}
// public void sendRequest(String request_url, int offsetIndex){
public void sendRequest(String request_url){
// request_url = request_url+offsetIndex;
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, request_url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for(int i = 0; i < response.length(); i++){
PersonUtils personUtils = new PersonUtils();
try {
JSONObject jsonObject = response.getJSONObject(i);
personUtils.setPersonFirstName(jsonObject.getString("name"));
personUtils.setJobProfile(jsonObject.getString("id"));
} catch (JSONException e) {
e.printStackTrace();
}
personUtilsList.add(personUtils);
}
mAdapter = new CustomRecyclerAdapter(MainActivity.this, personUtilsList);
recyclerView.setAdapter(mAdapter);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i("Volley Error: ", error.getMessage());
}
});
rq.add(jsonArrayRequest);
}
}
CustomRecyclerAdapter.java
public class CustomRecyclerAdapter extends RecyclerView.Adapter<CustomRecyclerAdapter.ViewHolder> {
private Context context;
private List<PersonUtils> personUtils;
public CustomRecyclerAdapter(Context context, List personUtils) {
this.context = context;
this.personUtils = personUtils;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_list_item, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemView.setTag(personUtils.get(position));
PersonUtils pu = personUtils.get(position);
holder.pName.setText(pu.getPersonFirstName());
holder.pJobProfile.setText(pu.getJobProfile());
}
#Override
public int getItemCount() {
return personUtils.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView pName;
public TextView pJobProfile;
public ViewHolder(View itemView) {
super(itemView);
pName = (TextView) itemView.findViewById(R.id.pNametxt);
pJobProfile = (TextView) itemView.findViewById(R.id.pJobProfiletxt);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
PersonUtils cpu = (PersonUtils) view.getTag();
Toast.makeText(view.getContext(), cpu.getPersonFirstName()+" "+" is "+ cpu.getJobProfile(), Toast.LENGTH_SHORT).show();
}
});
}
}
}
Required Output:
on loading call sendRequest(String request_url, int offsetIndex)
if user scroll then call sendRequest(String request_url, int offsetIndex)
Every request should return next 10 items
This is my LatestGradeAdapter
public class LatestGradeAdapter extends RecyclerView.Adapter<LatestGradeAdapter.RecyclerViewHolder> {
private Context mCtx;
private List<ListGradeData> sectionList;
public LatestGradeAdapter(Context mCtx, List<ListGradeData> sectionList) {
this.mCtx = mCtx;
this.sectionList = sectionList;
}
#NonNull
#Override
public RecyclerViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.section_data_list, parent, false);
return new LatestGradeAdapter.RecyclerViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerViewHolder holder, int position) {
final ListGradeData sections = sectionList.get(position);
//BIND DATA
holder.textViewSection.setText(sections.getSection());
holder.textViewLevel.setText(sections.getLevel());
holder.textViewSchoolYear.setText(sections.getSchoolyear());
}
#Override
public int getItemCount() {
return sectionList.size();
}
public class RecyclerViewHolder extends RecyclerView.ViewHolder {
//Variables for list
TextView textViewSection, textViewLevel, textViewSchoolYear;
//Variables for head section
TextView textHeaderSection, textHeaderLevel, textHeaderSchoolYear;
public RecyclerViewHolder(final View itemView) {
super(itemView);
textViewSection = (TextView) itemView.findViewById(R.id.textSection);
textViewLevel = (TextView) itemView.findViewById(R.id.textLevel);
textViewSchoolYear = (TextView) itemView.findViewById(R.id.textYear);
}
}
}`
This is my LatestGradeFragment
`public class LatestGradeFragment extends Fragment {
List<ListGradeData> sectionList;
RecyclerView recyclerView;
public static LatestGradeFragment newInstance() {
return new LatestGradeFragment();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_latest_grade, container, false);
//RecyclerView+CardView for section
recyclerView = (RecyclerView) rootView.findViewById(R.id.display_recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
sectionList = new ArrayList<>();
loadSection();
return rootView;
}
private void loadSection() {
StringRequest stringRequest = new StringRequest(Request.Method.GET, Constants.USER_GRADE,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
//converting the string to json array object
JSONArray array = new JSONArray(response);
//traversing through all the object
for (int i = 0; i < array.length(); i++) {
//getting product object from json array
JSONObject sections = array.getJSONObject(i);
//adding the product to product list
sectionList.add(new ListGradeData(
sections.getInt("id"),
sections.getString("section"),
sections.getString("level"),
sections.getString("schoolyear")
));
}
//creating adapter object and setting it to recyclerview
LatestGradeAdapter adapter = new LatestGradeAdapter(getActivity(), sectionList);
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
//adding our stringrequest to queue
Volley.newRequestQueue(getActivity().getApplicationContext()).add(stringRequest);
}
#Override
public String toString() {
return "HomeFragment";
}
}`
I tried everything what I've searched for and when I apply it, it doesn't work.
could anyone help me?
private boolean loading = true;
private int pastVisiblesItems, visibleItemCount, totalItemCount;
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if(dy > 0) //check for scroll down{
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
loading = false;
loadSection();
}
}
}
}
});
I try to downloading image from server with volley and show them in recyclerview.
it is work correctly but the downloading image is very low.
(the size of each image approximately 50 kb).
what can i do?
is there better and optimize code than it?
this is my helper class:
public class StartActivity {
// for recyclerView - downLoad Data
private static final int LIMIT = 6;
OnLoadMoreListener onLoadMoreListener;
int idImage = 1;
private List<StructUser> structList = new ArrayList<>();
private AdapterUser adapter;
private int CURRENT_ITEM = 1;
private Context context;
private String TAG = StartActivity.class.getSimpleName();
//----------------------------------------------------
public StartActivity(Context context) {
this.context = context;
}
public void getDataAndSetInRecyclerView(RecyclerView recyclerView) {
loadData(CURRENT_ITEM);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
adapter = new AdapterUser(recyclerView, structList, context);
onLoadMoreListener = new OnLoadMoreListener() {
#Override
public void onLoadMore() {
structList.add(null);
adapter.notifyDataSetChanged();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
structList.remove(structList.size() - 1);
// adapter.notifyItemRemoved(structList.size());
loadData(CURRENT_ITEM);
}
}, 2000);
}
};
adapter.setOnLoadMoreListener(onLoadMoreListener);
recyclerView.setAdapter(adapter);
}
private void loadData(final int CURRENT_ITEM) {
String url = Config.DATA_URL + CURRENT_ITEM;
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
ActivityMain.hideProgressBar();
try {
for (int i = 0; i < response.length(); i++) {
JSONObject jsonObject = response.getJSONObject(i);
StructUser structUser = new StructUser();
if (!jsonObject.isNull(Config.TAG_TITLE))
structUser.setNetworkImageView(jsonObject.getString(Config.TAG_TITLE));
if (!jsonObject.isNull(Config.TAG_IMAGE_URL)) {
structUser.setNetworkImageView(Config.IMG_SERVER + idImage + ".png");
idImage++;
}
structList.add(structUser);
}
adapter.notifyDataSetChanged();
adapter.setLoaded();
// not show progressBar at end of list when get all data
if (response.toString().contains("[]")) {
adapter.reachEndList();
Toast.makeText(context, "not More Data to Show", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// hide progressBar
ActivityMain.hideProgressBar();
Log.e(TAG, "Login Error: " + error.getMessage());
Toast.makeText(context,
error.getMessage(), Toast.LENGTH_LONG).show();
}
});
AppController.getInstance().addToRequestQueue(jsonArrayRequest, TAG);
this.CURRENT_ITEM = this.CURRENT_ITEM + LIMIT;
}
}
this is my adapter:
public class AdapterUser extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_LOADING = 1;
public int visibleThreshold = 2;
boolean isLoading;
private int lastVisibleItem, totalItemCount;
private List<StructUser> structList = new ArrayList<>();
private OnLoadMoreListener mOnLoadMoreListener;
private Context context;
// load image from server -------------------------------------------------
private static ImageLoader imageLoader = ImageLoader.getInstance();
public static DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.mipmap.ic_cloud_download)
.showImageForEmptyUri(R.mipmap.ic_picture)
.showImageOnFail(android.R.drawable.ic_dialog_alert)
.cacheInMemory(true)
.cacheOnDisk(false)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
//---------------------------------------------------------------
public AdapterUser(RecyclerView mRecyclerView, List<StructUser> structList, Context context) {
this.context = context;
this.structList = structList;
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
mRecyclerView.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 (!isLoading && totalItemCount <= visibleThreshold + (lastVisibleItem)) {
if (mOnLoadMoreListener != null) {
mOnLoadMoreListener.onLoadMore();
}
isLoading = true;
}
}
});
}
public void setLoaded() {
isLoading = false;
}
public void reachEndList() {
isLoading = true;
}
//========================================================
#Override
public int getItemViewType(int position) {
return structList.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
if (viewType == VIEW_TYPE_ITEM) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.adapter_start_activity , viewGroup, false);
return new UserViewHolder(view);
} else if (viewType == VIEW_TYPE_LOADING) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_loading_item, viewGroup, false);
return new LoadingViewHolder(view);
}
return null;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof UserViewHolder) {
UserViewHolder userViewHolder = (UserViewHolder) holder;
StructUser user = structList.get(position);
userViewHolder.title.setText(user.getTitle());
// load image from server
imageLoader.displayImage(user.getNetworkImageView(), userViewHolder.networkImageView, options);
} else if (holder instanceof LoadingViewHolder) {
LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder;
loadingViewHolder.progressBar.setIndeterminate(true);
}
}
#Override
public int getItemCount() {
return structList == null ? 0 : structList.size();
}
public void setOnLoadMoreListener(OnLoadMoreListener mOnLoadMoreListener) {
this.mOnLoadMoreListener = mOnLoadMoreListener;
}
class UserViewHolder extends RecyclerView.ViewHolder {
public TextView title;
// for download & cash image
public ImageView networkImageView;
public UserViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.txtTitle);
networkImageView = (ImageView) itemView.findViewById(R.id.networkImageView);
}
}
class LoadingViewHolder extends RecyclerView.ViewHolder {
public ProgressBar progressBar;
public LoadingViewHolder(View itemView) {
super(itemView);
progressBar = (ProgressBar) itemView.findViewById(R.id.progressBar1);
}
}
}
Use Glide for downloading Image...
Glide.with(ActivityName.this)
.load(image_url)
.into(imageView_object);
It will download image and set in ImageView.
I want to code endless scrolling with Adapters & RecyclerViews and I'm fetching my items with Volley from JSON. Though I have read these guides (Codepath and github), I'm finding it difficult to apply it to my own scenario.
The url of my json has these format: https://example.com/json/items?page=1, https://example.com/json/items?page=2, https://example.com/json/items?page=3 etc.
Below are the codes I'm using:
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
The link to the code is EndlessRecyclerViewScrollListener.
In the one in my project, I have deleted all the codes that concerns GridLayoutManager and StaggeredGridLayoutManager since I won't be needing them.
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;
}
}
I don't know if you could give me tips on how I could implement it to my RecyclerView. Thanks in advance.
You have to implement own listener to the adapter you are binding to recyclerview.
First create a interface like this,
public interface OnLoadMoreListener {
void onLoadMore();
}
In your recyclerview's adapter set this,
adapter.setOnLoadMoreListener(new OnLoadMoreListener() {
#Override
public void onLoadMore() {
//get your items here based on the pagination count
}
});
Your modified video adapter
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);
}
}
}
While initializing the adapter send recyclerview object
adapter = new VideoAdapter(mVideoItemsList, this, recyclerView );
Once you get your next set of items, increment your pagecount, notifyDataSetChanged() and call this
adapter.setLoaded();
Hope this will help you!