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
Related
I have to display 100 data on recycler-view. so I want to implement load more to make it efficient. when I tried to compile the code, the progress bar doesn't go and it leaves big space on the bottom. and it just loaded 20 data not all of them.
this is the code for my adapter
class LoadingViewHolder extends RecyclerView.ViewHolder{
public ProgressBar progressBar;
public LoadingViewHolder(#NonNull View itemView) {
super(itemView);
progressBar=(ProgressBar) itemView.findViewById(R.id.loadmore);
}
}
class herbalViewHolder extends RecyclerView.ViewHolder{
TextView namaHerbal,khasiatHerbal;
ImageView thumbnail;
public herbalViewHolder(#NonNull View itemView) {
super(itemView);
namaHerbal = itemView.findViewById(R.id.nama_herbal);
khasiatHerbal = itemView.findViewById(R.id.khasiat_herbal);
thumbnail = itemView.findViewById(R.id.gambar_herbal);
}
}
public class herbalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private final int VIEW_TYPE_ITEM=0,VIEW_TYPE_LOADING=1;
private loadMore loadMore;
boolean isLoading;
private Context mCtx;
List<herbalModel> herbalModelList;
int visibleThreshold=5;
int lastVisibleItem,totalItemCount;
public herbalAdapter(RecyclerView recyclerView,Context mCtx, List<herbalModel> herbalModelList) {
this.mCtx = mCtx;
this.herbalModelList = herbalModelList;
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager)recyclerView.getLayoutManager();
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
totalItemCount = linearLayoutManager.getItemCount();
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
if (!isLoading && totalItemCount <= (lastVisibleItem+visibleThreshold))
{
if (loadMore != null)
loadMore.onLoadMore();
isLoading=true;
}
}
});
}
#Override
public int getItemViewType(int position) {
return herbalModelList.get(position) == null ? VIEW_TYPE_LOADING:VIEW_TYPE_ITEM;
}
public void setLoadMore(loadMore loadMore) {
this.loadMore = loadMore;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
if(i == VIEW_TYPE_ITEM)
{
CardView v = (CardView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.cardview_herbal, parent,false);
// View view =inflater.inflate(R.layout.cardview_herbal,null);
return new herbalViewHolder(v);
}
else if(i == VIEW_TYPE_LOADING)
{
View view = LayoutInflater.from(mCtx).inflate(R.layout.item_loading,parent,false);
return new LoadingViewHolder(view);
}
return null;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder viewHolder, int i) {
if (viewHolder instanceof herbalViewHolder)
{
herbalModel detailherbal =herbalModelList.get(i);
herbalViewHolder herbalViewHolder = (herbalViewHolder) viewHolder;
herbalViewHolder.namaHerbal.setText(detailherbal.getNama());
herbalViewHolder.khasiatHerbal.setText(detailherbal.getKhasiat());
Glide.with(mCtx)
.load(detailherbal.getThumbnail())
.into(herbalViewHolder.thumbnail);
final String idHerbal =detailherbal.getId();
herbalViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(mCtx, detailHerbal.class);
i.putExtra("idHerbal", idHerbal);
mCtx.startActivity(i);
}
});
}
else if(viewHolder instanceof LoadingViewHolder)
{
LoadingViewHolder loadingViewHolder = (LoadingViewHolder) viewHolder;
loadingViewHolder.progressBar.setIndeterminate(true);
}
}
#Override
public int getItemCount() {
return herbalModelList.size();
}
public void setLoaded() {
isLoading = false;
}
public void filterlist (ArrayList<herbalModel> filteredList)
{
herbalModelList =filteredList;
notifyDataSetChanged();
}
}
this is the main activity for displaying recyclerview
private void get10Data() {
String url ="https://jsonplaceholder.typicode.com/photos";
JsonArrayRequest request = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray jsonArray) {
Log.d(TAG,"Onresponse"+jsonArray.toString());
for(int i = 0; i < 10; i++) {
try {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Log.d(TAG,"jsonobject"+jsonObject);
herbalModels.add(
new herbalModel(
jsonObject.getString("title"),
"Khasiat",
jsonObject.getString("albumId"),
jsonObject.getString("id"),
jsonObject.getString("thumbnailUrl")
)
);
}
catch(JSONException e) {
}
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Log.d(TAG,"Onerror"+volleyError.toString());
}
});
MySingleton.getInstance(getActivity()).addToRequestQueue(request);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_herbal, container, false);
herbalModels = new ArrayList<>();
RequestQueue queue = MySingleton.getInstance(this.getActivity().getApplicationContext()).getRequestQueue();
get10Data();
sortData(rootView);
StartRecyclerView(rootView);
return rootView ;
}
private void StartRecyclerView(View rootView) {
recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview_herbal);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new herbalAdapter(recyclerView,getActivity(),herbalModels);
recyclerView.setAdapter(adapter);
//set loaded more event
adapter.setLoadMore(new loadMore() {
#Override
public void onLoadMore() {
if (herbalModels.size() <= 20)
{
herbalModels.add(null);
adapter.notifyItemInserted(herbalModels.size()-1);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
herbalModels.remove(herbalModels.size()-1);
adapter.notifyItemRemoved(herbalModels.size());
final int index = herbalModels.size();
final int end = index+10;
String url ="https://jsonplaceholder.typicode.com/photos";
JsonArrayRequest request = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray jsonArray) {
Log.d(TAG,"Onresponse"+jsonArray.toString());
for(int i = index; i < end; i++) {
try {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Log.d(TAG,"jsonobject"+jsonObject);
herbalModels.add(
new herbalModel(
jsonObject.getString("title"),
"Khasiat",
jsonObject.getString("albumId"),
jsonObject.getString("id"),
jsonObject.getString("thumbnailUrl")
)
);
}
catch(JSONException e) {
}
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Log.d(TAG,"Onerror"+volleyError.toString());
}
});
MySingleton.getInstance(getActivity()).addToRequestQueue(request);
adapter.notifyDataSetChanged();
adapter.setLoaded();
}
},5000);
}
}
});
}
I have tried some code to can click recyclerview item and get position, but I can't click the recyclerview item.. the data I get from url. So I wan't switch activity with get the item user click..
how I can fix that?
this code for adapter
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
Context context;
private static final String TAG = RecyclerViewAdapter.class.getSimpleName();
List<GetDataAdapter> getDataAdapter;
ImageLoader imageLoader1;
public RecyclerViewAdapter(List<GetDataAdapter> getDataAdapter, Context context) {
super();
this.getDataAdapter = getDataAdapter;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_items, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder Viewholder, int position) {
GetDataAdapter getDataAdapter1 = getDataAdapter.get(position);
imageLoader1 = ServerImageParseAdapter.getInstance(context).getImageLoader();
imageLoader1.get(getDataAdapter1.getImageServerUrl(),
ImageLoader.getImageListener(
Viewholder.networkImageView,//Server Image
R.mipmap.ic_launcher,//Before loading server image the default showing image.
android.R.drawable.ic_dialog_alert //Error image if requested image dose not found on server.
)
);
Viewholder.networkImageView.setImageUrl(getDataAdapter1.getImageServerUrl(), imageLoader1);
Viewholder.ImageTitleNameView.setText(getDataAdapter1.getImageTitleName());
}
#Override
public int getItemCount() {
return getDataAdapter.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
public TextView ImageTitleNameView;
public NetworkImageView networkImageView;
public ViewHolder(View itemView) {
super(itemView);
ImageTitleNameView = (TextView) itemView.findViewById(R.id.textView_item);
networkImageView = (NetworkImageView) itemView.findViewById(R.id.VollyNetworkImageView1);
}
}
}
and this code for mainactivity
public class MainActivity extends AppCompatActivity {
List<GetDataAdapter> GetDataAdapter1;
RecyclerView recyclerView;
RecyclerView.LayoutManager recyclerViewlayoutManager;
RecyclerView.Adapter recyclerViewadapter;
String GET_JSON_DATA_HTTP_URL = "http://androidblog.esy.es/ImageJsonData.php";
String JSON_IMAGE_TITLE_NAME = "image_title";
String JSON_IMAGE_URL = "image_url";
JsonArrayRequest jsonArrayRequest ;
RequestQueue requestQueue ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GetDataAdapter1 = new ArrayList<>();
recyclerView = (RecyclerView) findViewById(R.id.recyclerview1);
recyclerView.setHasFixedSize(true);
recyclerViewlayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(recyclerViewlayoutManager);
JSON_DATA_WEB_CALL();
}
public void JSON_DATA_WEB_CALL(){
jsonArrayRequest = new JsonArrayRequest(GET_JSON_DATA_HTTP_URL,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
JSON_PARSE_DATA_AFTER_WEBCALL(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue = Volley.newRequestQueue(this);
requestQueue.add(jsonArrayRequest);
}
public void JSON_PARSE_DATA_AFTER_WEBCALL(JSONArray array){
for(int i = 0; i<array.length(); i++) {
GetDataAdapter GetDataAdapter2 = new GetDataAdapter();
JSONObject json = null;
try {
json = array.getJSONObject(i);
GetDataAdapter2.setImageTitleNamee(json.getString(JSON_IMAGE_TITLE_NAME));
GetDataAdapter2.setImageServerUrl(json.getString(JSON_IMAGE_URL));
} catch (JSONException e) {
e.printStackTrace();
}
GetDataAdapter1.add(GetDataAdapter2);
}
recyclerViewadapter = new RecyclerViewAdapter(GetDataAdapter1, this);
recyclerView.setAdapter(recyclerViewadapter);
}
}
getdataadapter
public class GetDataAdapter {
public String ImageServerUrl;
public String ImageTitleName;
public String getImageServerUrl() {
return ImageServerUrl;
}
public void setImageServerUrl(String imageServerUrl) {
this.ImageServerUrl = imageServerUrl;
}
public String getImageTitleName() {
return ImageTitleName;
}
public void setImageTitleNamee(String Imagetitlename) {
this.ImageTitleName = Imagetitlename;
}
}
You need to set onClickListener to your item view. You can do by following below steps:
Set onCLickListener to root view of your list item.
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_items, parent, false);
Add below code in onCreateViewHolder:
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Add your logic here
}
});
You can add listener while onBindViewHolder:
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Add your logic here
}
});
Thanks.
Put a listener on your recycler item view and then in onclick, start intent to open new activity. Pass the data object you want to pass with the intent.
//make sure your model class GetDataAdapter implements Parcelable
holder.itemView.setOnclickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(this, ActivityToOpen.class);
intent.putExtra("key",Your Object to pass);// getDataAdapter1 in your case
context.startActivity(intent);
}
});
then in your Startted activity receive your object like this
YourObject obj = getIntent().getParcelableExtra("key");
//Your case
GetDataAdapter obj = getIntent().getParcelableExtra("key");
I am using RecyclerView to display my products, problem is when if I select the first products and scroll down to the end of list I see different products selected and when i scroll back to top of list the first item is not selected.
My Adapter
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
String u = "http://192.185.52.231/~sabby070/hyype/";
Context context1;
private java.util.List<ProductDetails> List;
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_list, parent, false);
return new MyViewHolder(itemView);
}
public RecyclerAdapter(List<ProductDetails> DataList, FragmentActivity activity) {
this.List = DataList;
context1 = activity;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView Likecount;
public ImageView Image;
public ImageView Imagelike, ImageUnlike;
public MyViewHolder(View view) {
super(view);
Likecount = (TextView) view.findViewById(R.id.textView_itemPrice);
Image = (ImageView) view.findViewById(R.id.imageView_imgtosold);
Imagelike = (ImageView)view.findViewById(R.id.Like_Button);
ImageUnlike = (ImageView)view.findViewById(R.id.UnLike_Button);
}
}
#Override
public void onBindViewHolder(final RecyclerAdapter.MyViewHolder holder, final int position) {
final ProductDetails detail = List.get(position);
holder.Likecount.setText(detail.getLikeCount());
Glide.with(context1).load(u+detail.getImage()).override(600, 200).diskCacheStrategy(DiskCacheStrategy.ALL).into(holder.Image);
holder.Image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context1, ""+position, Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context1, Buy_Product.class);
intent.putExtra("Product Name",detail.getLikeCount());
intent.putExtra("Product Image",detail.getImage());
context1.startActivity(intent);
}
});
holder.Imagelike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.Imagelike.getVisibility()==View.VISIBLE)
{
holder.Imagelike.setVisibility(View.GONE);
holder.ImageUnlike.setVisibility(View.VISIBLE);
}
}
});
holder.ImageUnlike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.ImageUnlike.getVisibility()==View.VISIBLE)
{
holder.Imagelike.setVisibility(View.VISIBLE);
holder.ImageUnlike.setVisibility(View.GONE);
}
}
});
}
#Override
public int getItemCount() {
return List.size();
}
}
My class
public class Men_Fragment extends Fragment {
static String URL = "http://192.185.52.231/~sabby070/hyype/index.php?action=timeline&user_id=53&post_category=timeline";
private List<ProductDetails> DataList = new ArrayList<>();
private RecyclerView recyclerView;
private RecyclerAdapter rAdapter;
String img;
String a;
Boolean list[];
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_men_, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.men_recycler_view);
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(response);
for (int i = 0; i < response.length(); i++) {
JSONObject obj = jsonObject.getJSONObject(String.valueOf(i));
a = obj.getString("like_count");
img = obj.getString("video_thumb");
final ProductDetails details = new ProductDetails(a, img);
DataList.add(details);
rAdapter = new RecyclerAdapter(DataList, getActivity());
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 2);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(rAdapter);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), "" + error, Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
requestQueue.add(stringRequest);
return view;
}
}
You have to take List(with boolean) and store selected values in that list and then use those values in onBindView()
In your ProductDetails class add a field boolean selected;
In your onClick() add List.get(position).setSelected(!List.get(position).isSelected()); to check/uncheck as needed.
Finaly in your onBindViewHolder(...) add
if(List.get(position).isSelected()){
holder.Imagelike.setVisibility(View.VISIBLE);
}else{
holder.ImageUnlike.setVisibility(View.GONE);
}
This is my code file.
public class FragmentOfferList extends ListFragment {
private RecyclerView recyclerView;
private String TAG = FragmentOfferList.class.getSimpleName();
private static final String endpoint = "http://example.com/offer/offers.json";
private List<Offer> offers = new ArrayList<>();
private ProgressDialog pDialog;
RecyclerView.Adapter adapter;
public FragmentOfferList() {
}
public static FragmentOfferList newInstance(int num) {
FragmentOfferList f = new FragmentOfferList();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pDialog = new ProgressDialog(getActivity());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.recycler_list, container, false);
recyclerView = (RecyclerView) v.findViewById(R.id.recycler_view);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
adapter = new MyAdapter(offers, getActivity());
recyclerView.setAdapter(adapter);
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new ClickListener() {
#Override
public void onClick(View view, int position) {
Offer offer = Utility.getOffers().get(position);
Intent intent = new Intent(getActivity(), ActivityProductList.class);
intent.putExtra("query", offer.getQuery());
startActivity(intent);
//startActivity(new Intent(getActivity(), ActivityProductList.class));
}
#Override
public void onLongClick(View view, int position) {
}
}));
if (Utility.getOffers().size() == 0){
fetchOffers();
}
else{
Utility.displayToast("here");
offers = Utility.getOffers();
adapter.notifyDataSetChanged();
}
return v;
}
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<Offer> offers;
private Context context;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView title, year, offer;
ImageView imageView;
public MyViewHolder(View view) {
super(view);
imageView = (ImageView) view.findViewById(R.id.thumbnail);
title = (TextView) view.findViewById(R.id.title);
offer = (TextView) view.findViewById(R.id.offer);
}
}
public MyAdapter(List<Offer> offers, Context context) {
this.offers = offers;
this.context = context;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_offer, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Offer offer = offers.get(position);
holder.title.setText(offer.getName());
holder.offer.setText(offer.getOffer());
Glide.with(context).load(String.valueOf(offer.getUrl()))
.error(R.drawable.placeholder)
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(holder.imageView);
}
#Override
public int getItemCount() {
return offers.size();
}
}
private void fetchOffers() {
pDialog.setMessage("Downloading json...");
pDialog.show();
JsonArrayRequest req = new JsonArrayRequest(endpoint,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
pDialog.hide();
offers.clear();
for (int i = 0; i < response.length(); i++) {
try {
JSONObject object = response.getJSONObject(i);
Offer offer = new Offer();
offer.setOffer(object.getString("offer"));
offer.setName(object.getString("name"));
offer.setUrl(object.getString("url"));
offer.setQuery(object.getString("query"));
offers.add(offer);
} catch (JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
}
}
Utility.setOffers(offers);
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Error: " + error.getMessage());
pDialog.hide();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(req);
}
}
First time when Utility.getoffers().size() is 0, it fetches data, save it in Utility.setOffers(offers) and display on screen as expected. But next time (go back and to same activity), Utility.getoffers().size() is not 0 , i got data directly from Utility.getBrands().
After that i called adapter.notifyDataSetChaned(), but it is not working. Not working menas even though data sise is more than 0 but no data rendering on screen?
What is wrong here? am i missing anything?
You are not updating your offers list, but rather replacing it with another list that your adapter has no reference to. To fix this you can do the following:
offers.clear();
offers.addAll(Utility.getOffers());
adapter.notifyDataSetChanged();
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!