I m trying to extract android volley response to a member variable of the same class. I used callback interfaces to perform this task :
public void getData(MyCustomListener customListener) {
JsonArrayRequest arrayRequest = new JsonArrayRequest(Request.Method.POST, url,
response -> {
Log.i("response",response.toString());
customListener.onResponse(completeCart);
},
error -> Log.i("Volley_error", error.getMessage())) {
...
CustomerListener interface:
public interface MyCustomListener {
public void onResponse(Object response);
public void onError(String error_response);
}
And inside onCreateView method of the fragment :
getData(new MyCustomListener() {
#Override
public void onResponse(Object response) {
completeCartProItems.addAll((List<CompleteCartProItem>) response);
}
#Override
public void onError(String error_response) {}
});
When I put a debug pointer at completeCartProItems.addAll((List<CompleteCartProItem>) response); response is not empty but completeCartProItems arraylist is shown as empty.
Variables :
I need to pass this completeCartProItems to a Adapter named CartItem_ScrollerAdapter which has implemented to a RecycleView.
This implementation also inside the onCreateView of the fragment. right after calling getData() method :
cart_item_scrollerAdapter = new CartItem_ScrollerAdapter(getActivity(), completeCartProItems);
I put debug pointer inside the constructor of the CartItem_ScrollerAdapter as well.
But it also shows that the List parameter of the constructor is empty.
How to pass not empty ArrayList to the adapter given below ?? Any suggestions will be appreciable. Thank you.
UPDATE
Adapter class :
public class CartItem_ScrollerAdapter extends RecyclerView.Adapter<CartItem_ScrollerAdapter.CartItemViewHolder> {
private LayoutInflater inflater;
private List<CompleteCartProItem> completeCartProItems = new ArrayList<>();
private Context context;
public CartItem_ScrollerAdapter(Context context, List<CompleteCartProItem> completeCartProItems) {
this.inflater = LayoutInflater.from(context);
this.context = context;
this.completeCartProItems = completeCartProItems;
}
#Override
public CartItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.cart_item, parent, false);
CartItemViewHolder cartItemViewHolder = new CartItemViewHolder(view);
return cartItemViewHolder;
}
#Override
public void onBindViewHolder(CartItemViewHolder holder, int position) {
CompleteCartProItem proItem = completeCartProItems.get(position);
CartDetails details = (CartDetails) MyApplication.getAndroidSession().getAttribute("cart");
holder.cart_pro_name.setText(proItem.getP_name());
holder.cart_pro_price.setText("Rs " + (proItem.getP_dscPer() != 0 ? details.getDiscountPrice(proItem.getP_price(), proItem.getP_dscPer()) : proItem.getP_price()));
holder.cart_pro_qnty.setText(details.getQntyOfProduct(proItem.getPid(), proItem.getP_size()) + "");
holder.cart_pro_size.setText(proItem.getP_size());
String image_url = "http://10.0.2.2:8080/ECommerceApp/" + proItem.getP_img();
Picasso.with(context).load(image_url).into(holder.cart_pro_img);
}
#Override
public int getItemCount() {
return completeCartProItems != null ? completeCartProItems.size() : 0;
}
class CartItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView cart_pro_name;
TextView cart_pro_price;
TextView cart_pro_qnty;
TextView cart_pro_size;
ImageView cart_pro_img;
ImageButton cart_remove_btn;
Button cart_change;
public CartItemViewHolder(View itemView) {
super(itemView);
cart_pro_name = (TextView) itemView.findViewById(R.id.cart_item_product_name);
cart_pro_price = (TextView) itemView.findViewById(R.id.cart_item_product_price);
cart_pro_size = (TextView) itemView.findViewById(R.id.cart_item_size);
cart_pro_img = (ImageView) itemView.findViewById(R.id.cart_product_img);
cart_pro_qnty = (TextView) itemView.findViewById(R.id.cart_item_qnty);
//===============================================================================================
cart_remove_btn = (ImageButton) itemView.findViewById(R.id.remove_item_btn);
cart_change = (Button) itemView.findViewById(R.id.cart_item_change_btn);
cart_pro_img.setOnClickListener(this);
cart_remove_btn.setOnClickListener(this);
cart_change.setOnClickListener(this);
}
#Override
public void onClick(View v) {
}
}
}
Fragment :
public class CartFragment extends Fragment {
private RecyclerView cart_horizontal_scroller;
private CartItem_ScrollerAdapter cart_item_scrollerAdapter;
private Button purchase_button;
private List<CompleteCartProItem> completeCartProItems = new ArrayList<>();
public CartFragment() {
// Required empty public constructor
}
public void getData(MyCustomListener<CompleteCartProItem> customListener) {
if (MyApplication.getAndroidSession().getAttribute("cart") != null) {
Log.i("cart_null", "NOT null");
RequestQueue requestQueue = VolleySingleton.getsInstance().getRequestQueue();
CartDetails cartDetails = (CartDetails) MyApplication.getAndroidSession().getAttribute("cart");
CopyOnWriteArrayList<CartItem> jsonSendArray = cartDetails.getShoppingList();
final String jsonString = new Gson().toJson(jsonSendArray,
new TypeToken<CopyOnWriteArrayList<CartItem>>() {
}.getType());
Log.i("json_object", jsonString);
String url = "http://10.0.2.2:8080/ECommerceApp/getAllProductsAction";
JsonArrayRequest arrayRequest = new JsonArrayRequest(Request.Method.POST, url,
response -> {
List<CompleteCartProItem> completeCart = new Gson().fromJson(response.toString(),
new TypeToken<List<CompleteCartProItem>>() {
}.getType());
Log.i("response", completeCart.get(0).getP_name());
customListener.onResponse(completeCart);
}, error -> Log.i("Volley_error", error.getMessage())) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("Content-Type", "application/json");
params.put("cartList", jsonString);
return params;
}
};
arrayRequest.setRetryPolicy(new RetryPolicy() {
#Override
public int getCurrentTimeout() {
return 5000;
}
#Override
public int getCurrentRetryCount() {
return 5000;
}
#Override
public void retry(VolleyError error) throws VolleyError {
}
});
requestQueue.add(arrayRequest);
} else {
Log.i("cart_null", "null");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_cart, container, false);
cart_horizontal_scroller = (RecyclerView) view.findViewById(R.id.horizontal_scrollView_cart_items);
getData(new MyCustomListener<CompleteCartProItem>() {
#Override
public void onResponse(List<CompleteCartProItem> response) {
completeCartProItems.addAll(response);
//completeCartProItems.add(new CompleteCartProItem(1, 2340.0, "Extra Orient Top", "Orient", "", "S", 5));
Log.i("check", completeCartProItems.get(0).getP_name());
}
#Override
public void onError(String error_response) {
}
});
cart_item_scrollerAdapter = new CartItem_ScrollerAdapter(getActivity(), completeCartProItems);
cart_horizontal_scroller.setAdapter(cart_item_scrollerAdapter);
cart_horizontal_scroller.setLayoutManager(new LinearLayoutManager(getActivity(),
LinearLayoutManager.HORIZONTAL, false));
purchase_button = (Button) view.findViewById(R.id.purchase_btn);
purchase_button.setOnClickListener(v -> {
Toast t = Toast.makeText(getActivity(), "Worked", Toast.LENGTH_LONG);
t.show();
});
return view;
}
}
Ok. In reference to the comment above, I am writing some steps you should try since I do not have a clear picture of what might be wrong.
Let's start with your MyCustomListener. I do not know why are you setting the response type to Object. If it is to use this in multiple requests then you can modify it like the following with generics
public interface MyCustomListener<T> {
public void onResponse(T response);
public void onError(String error_response);
}
then use it like this when a callback is needed
getData(new MyCustomListener<List<CompleteCartProItem>>() {
#Override
public void onResponse(List<CompleteCartProItem> response) {
completeCartProItems.addAll(response);
}
#Override
public void onError(String error_response) {
//handle error
}
});
Also make sure you are not re-initialising completeCartProItems elsewhere after the callback.
Not really sure if the following will fix your issue but make sure that your callback is executed in the UI thread, too.
Related
when I send new data or update the info, how can to change my recycle view?
I have used a dapter.notifyDataSetChanged(); , but it's not working...
I tried more method, but it all cannot change my recycler view
in my code
recyclerView = view.findViewById(R.id.recyclerCoin);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
listCoinDiamondModel = new ArrayList<>();
requestQueue = Volley.newRequestQueue(getActivity());
getData();
adapter = new CoinAdapter(listCoinDiamondModel, getActivity());
recyclerView.setAdapter(adapter);
private void sendGift(String postUserID) {
final String postUserIDD = postUserID;
final String GiftAmount = this.GiftAmount.getText().toString().trim();
final String flag = "1";
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_GIFTCOIN,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
String success = jsonObject.getString("success");
if (success.equals("1")){
adapter.notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),"Error" + error.toString(), Toast.LENGTH_SHORT).show();
}
})
{
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
//Log.d("FID", fid);
params.put("fid", fid);
params.put("GiftAmount", GiftAmount);
params.put("flag", flag);
params.put("postUserID", postUserIDD);
params.put("uid", getID);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(stringRequest);
}
private JsonArrayRequest getDataFromServer(int requestCount) {
//Initializing ProgressBar
final ProgressDialog progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Load...");
progressDialog.dismiss();
final String GROUP_LIST = "https://example.com/aaa.php?flag=1&fid="+ getActivity().getIntent().getStringExtra("fid") +"&page="+requestCount;
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(GROUP_LIST,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
parseData(response);
progressDialog.dismiss();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Toast.makeText(getActivity(), "No More gift Available", Toast.LENGTH_SHORT).show();
}
});
//Returning the request
return jsonArrayRequest;
}
//This method will get data from the web api
private void getData() {
requestQueue.add(getDataFromServer(requestCount));
requestCount++;
}
//This method will parse json data
private void parseData(JSONArray array) {
for (int i = 0; i < array.length(); i++) {
//Creating the newFeedModel object
final CoinDiamondModel coinDiamondModel = new CoinDiamondModel();
JSONObject json = null;
try {
//Getting json
json = array.getJSONObject(i);
String TAG_Coin = "Coin";
String TAG_Diamond = "Diamond";
String TAG_UserName = "UserName";
String TAG_UserPhoto = "UserPhoto";
String TAG_UserID = "UserID";
//Log.d("NAME111", json.getString(json.getString(TAG_UserName)));
coinDiamondModel.setCoin(json.getString(TAG_Coin));
coinDiamondModel.setDiamond(json.getString(TAG_Diamond));
coinDiamondModel.setGiftFromUserName(json.getString(TAG_UserName));
coinDiamondModel.setGiftFromUserPhoto(json.getString(TAG_UserPhoto));
coinDiamondModel.setGiftFromUserID(json.getString(TAG_UserID));
} catch (JSONException e) {
e.printStackTrace();
}
//Adding the newFeedModel object to the list
listCoinDiamondModel.add(coinDiamondModel);
//adapter.addTheCoinData(coinDiamondModel);
}
//Notifying the adapter that data has been added or changed
adapter.notifyDataSetChanged();
}
who knows what's happen and how can solve this?
could you told me how can I do, please?
adapter all code
public class CoinAdapter extends RecyclerView.Adapter<CoinAdapter.ViewHolder> {
private ImageLoader imageLoader;
private List<CoinDiamondModel> newcoinDiamondLists;
private RequestManager glide;
private Context context;
SessionManager sessionManager;
private String getID,memail;
public CoinAdapter(List<CoinDiamondModel> newcoinDiamondLists, Context context) {
this.newcoinDiamondLists = newcoinDiamondLists;
this.glide = Glide.with(context);
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.coinlist, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
sessionManager = new SessionManager(getApplicationContext());
sessionManager.checkLogin();
HashMap<String, String> user = sessionManager.getUserDetail();
getID = user.get(sessionManager.USERID);
memail = user.get(sessionManager.EMAIL);
//String gid = getIntent.getStringExtra("xxx");
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
CoinDiamondModel newCoinDiamondModel = newcoinDiamondLists.get(position);
imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader();
holder.userName.setText(newCoinDiamondModel.getGiftFromUserName());
holder.userID.setText(newCoinDiamondModel.getGiftFromUserID());
holder.coinCount.setText(" x "+newCoinDiamondModel.getCoin());
glide.load(newCoinDiamondModel.getGiftFromUserPhoto()).into(holder.userPhoto);
}
#Override
public int getItemCount() {
return newcoinDiamondLists.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
CircleImageView userPhoto;
TextView userName,userID,coinCount;
ImageView coinImg;
public ViewHolder(#NonNull View itemView) {
super(itemView);
userPhoto = (CircleImageView) itemView.findViewById(R.id.userPhoto);
userName = (TextView) itemView.findViewById(R.id.userName);
coinCount = (TextView) itemView.findViewById(R.id.coinCount);
userID = (TextView) itemView.findViewById(R.id.userID);
coinImg = (ImageView) itemView.findViewById(R.id.coinImg);
}
}
public void addTheCoinData(CoinDiamondModel coinDiamondModel){
if(coinDiamondModel!=null){
newcoinDiamondLists.add(coinDiamondModel);
notifyDataSetChanged();
}else {
throw new IllegalArgumentException("無資料!");
}
}
}
you can again set the adapter to recycler view after the response of the server
public void onResponse(JSONArray response) {
parseData(response);
progressDialog.dismiss();
adapter = new CoinAdapter(listCoinDiamondModel, getActivity());
recyclerView.setAdapter(adapter);
}
solution 2:
in your adapter write a function to update you list
and call function in activity
add this function to the adapter
public void updateList(List<CoinDiamondModel> list){
newcoinDiamondLists = list;
notifyDataSetChanged();
}
and call a function updateList of when you need an update recyclerview
The RecyclerView initialization and notifyDataSetChanged() is used properly. As your question is not clear enough about the Adapter implementation of the RecyclerView, I can give you several suggestions to check.
In RecyclerView.Adapter check if getItemCount() method is properly overriden with returning the list length (not 0) like below:
#Override
public int getItemCount() {
return listdata.length;
}
In RecyclerView.Adapter check if onCreateViewHolder method is properly overriden with proper xml layout like below:
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View listItem= layoutInflater.inflate(R.layout.coin_xml_layout, parent, false);
ViewHolder viewHolder = new ViewHolder(listItem);
return viewHolder;
}
In RecyclerView.Adapter check if RecyclerView.ViewHolder class is properly extended
and linked the UI elements from the xml with the adapter like below:
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView coinTextView;
public ViewHolder(View itemView) {
super(itemView);
this.coinTextView = (TextView) itemView.findViewById(R.id.coinTextView);
}
}
In RecyclerView.Adapter check if onBindViewHolder method is properly overridden and updated the list component UI properly like below:
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final MyListData myListData = listdata[position];
holder.cointTextView.setText(listdata[position].getCoin());
}
Debug with a breakpoint and check if the listCoinDiamondModel.add(coinDiamondModel) is calling or not and coinDiamondModel object is not empty.
The RecyclerView is placed properly in the activity xml, like the RecyclerView is Visible, has a decent size to show list elements. As an example:
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
you can update your adapter list manually like this:(write this function in your adapter)
public void updateCoinAdapterList(ArrayList<listCoinDiamondModel> recyclerItemsList) {
this.recyclerItemsList = recyclerItemsList;
this.notifyDataSetChanged();
}
you must set your adapter global variable and initialize it in OnCreate or OnResume, and call
adapter.updateCoinAdapterList(listCoinDiamondModel);
when your list changed
I have this silly problem.
I searched for it but couldn't get any anwser hence I posted it here.
In following fragment I have recyclerview which populate data from server with Post POJO with help of Gson.
I have use similar code many times in my another projects, but today I got an error due to which my recyclerview is not showing values. So I debug code and I got following output which shows 'this' is not available for my recycleview inside onResponse of Volley.
My Fragment class is as follows:
public class Seller_Corner_Tab2 extends Fragment implements PostAdapter.OnItemClickListener {
public static final String TAG = Seller_Corner_Tab2.class.getSimpleName();
RecyclerView recyclerView;
ProgressDialog progressDialog;
AppPreferences preferences;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.seller_corner_tab2,container,false);
preferences = new AppPreferences(getActivity());
recyclerView = (RecyclerView)view.findViewById(R.id.seller_corner_2_rv);
LinearLayoutManager mLinearLayoutManagerVertical = new LinearLayoutManager(getContext()); // (Context context)
mLinearLayoutManagerVertical.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(mLinearLayoutManagerVertical);
progressDialog = new ProgressDialog(getContext());
/*progressDialog.setMessage("Loading your Posts");
progressDialog.setCancelable(false);
progressDialog.show();*/
fetchSellerPosts();
return view;
}
public void fetchSellerPosts() {
final Seller seller = EKrushiKattaApplication.getInstance().getPrefManager().getSeller();
StringRequest strReq = new StringRequest(Request.Method.POST,
EndPoints.GETPOSTBYID, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
ArrayList<Post>templist = new ArrayList<>();
/*progressDialog.hide();*/
try {
GsonBuilder gsonbuilder= new GsonBuilder();
Gson gson=gsonbuilder.create();
Log.e("Response",response);
templist =gson.fromJson(response, new TypeToken<List<Post>>(){}.getType());
}catch (Exception e)
{
e.printStackTrace();
}
recyclerView.setAdapter( new PostAdapter(templist,getContext(),Seller_Corner_Tab2.this));
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.hide();
NetworkResponse networkResponse = error.networkResponse;
Log.e(TAG, "Connection error: " + error.getMessage() + ", code: " + networkResponse);
Toast.makeText(getActivity(), "Volley error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put(CommonLib.SELLER_ID,String.valueOf(seller.getSellerId()));
Log.e(TAG, "params: " + params.toString());
return params;
}
};
//Adding request to request queue
EKrushiKattaApplication.getInstance().addToRequestQueue(strReq);
}
#Override
public void onItemClick(Post post) {
}}
My debugger showing me this output
My PostAdapter Class is as follows :
public class PostAdapter extends RecyclerView.Adapter<PostAdapter.ViewHolder>{
private ArrayList<Post> posts;
private Context context;
private OnItemClickListener listener;
public PostAdapter(ArrayList<Post> posts, Context context, OnItemClickListener listener) {
this.posts = posts;
this.context = context;
this.listener = listener;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_post, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
if(posts!=null){
final Post post = posts.get(position);
holder.title.setText(post.getPostTitle());
holder.desc.setText(post.getPostDescription());
holder.cost.setText(post.getPostCost());
RequestOptions options = new RequestOptions()
.centerCrop()
// .placeholder(R.drawable.placeholder)
// .error(R.drawable.ic_pic_error)
.priority(Priority.HIGH);
new GlideImageLoader(holder.image,
holder.progressBar).load(EndPoints.BASE_URL+post.getPostImage(),options);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(post);
}
});
}
}
#Override
public int getItemCount() {
int size=0;
try {
size = posts.size();
} catch (Exception e) {
e.printStackTrace();
}
return size;
}
#Override
public long getItemId(int position) {
return super.getItemId(position);
}
class ViewHolder extends RecyclerView.ViewHolder{
ImageView image;
TextView title,desc,cost;
ProgressBar progressBar;
public ViewHolder(View itemView) {
super(itemView);
image=(ImageView)itemView.findViewById(R.id.post_item_image);
title=(TextView)itemView.findViewById(R.id.post_item_title);
desc=(TextView)itemView.findViewById(R.id.post_item_desc);
cost=(TextView)itemView.findViewById(R.id.post_item_cost);
progressBar=(ProgressBar)itemView.findViewById(R.id.post_item_progressbar);
}
}
public interface OnItemClickListener {
void onItemClick(Post post);
}}
Try this:
1) Pull the data source creation out of the onResponse()
2) Create adapter right after recycler view inflation.
3) In onResponse() fill data source with new data.
4) Call notifyDatasetChanged() in adapter.
public class Seller_Corner_Tab2 extends Fragment implements PostAdapter.OnItemClickListener {
public static final String TAG = Seller_Corner_Tab2.class.getSimpleName();
RecyclerView recyclerView;
ProgressDialog progressDialog;
AppPreferences preferences;
ArrayList<Post>templist = new ArrayList<>();
PostAdapter adapter;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.seller_corner_tab2,container,false);
preferences = new AppPreferences(getActivity());
recyclerView = (RecyclerView)view.findViewById(R.id.seller_corner_2_rv);
LinearLayoutManager mLinearLayoutManagerVertical = new LinearLayoutManager(getContext()); // (Context context)
mLinearLayoutManagerVertical.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(mLinearLayoutManagerVertical);
progressDialog = new ProgressDialog(getContext());
adapter = new PostAdapter(templist,getContext(),this);
recyclerView.setAdapter(adapter);
/*progressDialog.setMessage("Loading your Posts");
progressDialog.setCancelable(false);
progressDialog.show();*/
fetchSellerPosts();
return view;
}
public void fetchSellerPosts() {
final Seller seller = EKrushiKattaApplication.getInstance().getPrefManager().getSeller();
StringRequest strReq = new StringRequest(Request.Method.POST,
EndPoints.GETPOSTBYID, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
ArrayList<Post> newList = new ArrayList();
/*progressDialog.hide();*/
try {
GsonBuilder gsonbuilder= new GsonBuilder();
Gson gson=gsonbuilder.create();
Log.e("Response",response);
templist =gson.fromJson(response, new TypeToken<List<Post>>(){}.getType());
}catch (Exception e)
{
e.printStackTrace();
}
templist.addAll(newList);
adapter.notifyDatasetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.hide();
NetworkResponse networkResponse = error.networkResponse;
Log.e(TAG, "Connection error: " + error.getMessage() + ", code: " + networkResponse);
Toast.makeText(getActivity(), "Volley error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put(CommonLib.SELLER_ID,String.valueOf(seller.getSellerId()));
Log.e(TAG, "params: " + params.toString());
return params;
}
};
//Adding request to request queue
EKrushiKattaApplication.getInstance().addToRequestQueue(strReq);
}
#Override
public void onItemClick(Post post) {
}}
I have successfully to get next page of post using Blogger's API, but i can't achieve the smooth scrolling of recyclerview, it look lagging.
I have tried using recyclerViewData.setNestedScrollingEnabled(false) and adapter.notifyDataSetChanged() but still doesn't work.
My point is How to achieve smooth of recyclerview. Any suggestion will be appreciate. thank is advance.
Here is my code
private void getData() {
showLoading(true);
final Call<ResponseBlogPost> postList = apiService.getListPost(GlobalVariable.APP_KEY);
postList.enqueue(new Callback<ResponseBlogPost>() {
#Override
public void onResponse(Call<ResponseBlogPost> call, Response<ResponseBlogPost> response) {
showLoading(false);
ResponseBlogPost responseBlogPost = response.body();
initDataView(responseBlogPost);
}
#Override
public void onFailure(Call<ResponseBlogPost> call, Throwable t) {
showLoading(false);
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
private void initDataView(ResponseBlogPost listpost){
GlobalFunction.saveString(this,GlobalVariable.TOKEN_PAGINATION, listpost.getNextPageToken());
final String nextPageToken = GlobalFunction.getStrings(this, GlobalVariable.TOKEN_PAGINATION);
itemsList.addAll(listpost.getItems());
adapter = new MainAdapter(itemsList) {
#Override
public void load() {
if(nextPageToken==null){
return;
}
getNextListPost();
}
};
recyclerViewData.setAdapter(adapter);
recyclerViewData.setHasFixedSize(true);
staggeredGridLayoutManager = new StaggeredGridLayoutManager(2,1);
staggeredGridLayoutManager.setGapStrategy(0);
recyclerViewData.setLayoutManager(staggeredGridLayoutManager);
}
private void getNextListPost(){
showLoading(true);
final String nextPageToken = GlobalFunction.getStrings(this, GlobalVariable.TOKEN_PAGINATION);
Call<ResponseBlogPost> call = apiService.getNexPageListPost(GlobalVariable.APP_KEY,nextPageToken);
call.enqueue(new Callback<ResponseBlogPost>() {
#Override
public void onResponse(Call<ResponseBlogPost> call, Response<ResponseBlogPost> response) {
showLoading(false);
ResponseBlogPost responseModel = response.body();
if(nextPageToken!=null){
initDataView2(responseModel);
}else{
Toast.makeText(MainActivity.this, "tidak ada data lagi ya", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<ResponseBlogPost> call, Throwable t) {
showLoading(false);
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
private void initDataView2(ResponseBlogPost listpost){
GlobalFunction.saveString(this,GlobalVariable.TOKEN_PAGINATION, listpost.getNextPageToken());
final String nextPageToken = GlobalFunction.getStrings(this, GlobalVariable.TOKEN_PAGINATION);
itemsList.addAll(listpost.getItems());
adapter = new MainAdapter(itemsList) {
#Override
public void load() {
if(nextPageToken!=null){
getNextListPost();
}
}
};
recyclerViewData.setAdapter(adapter);
recyclerViewData.setHasFixedSize(true);
staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, 1);
staggeredGridLayoutManager.setGapStrategy(0);
recyclerViewData.setLayoutManager(staggeredGridLayoutManager);
}
My Adapter Code :
public abstract class MainAdapter extends RecyclerView.Adapter<MainAdapter.MainViewHolder>{
private List<BlogPostModel> responseBlogPost;
public MainAdapter(List<BlogPostModel> responseBlogPost) {
this.responseBlogPost = responseBlogPost;
}
public abstract void load();
#Override
public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_main,parent,false);
return new MainViewHolder(view);
}
#Override
public void onBindViewHolder(final MainViewHolder holder, int position) {
final BlogPostModel model = responseBlogPost.get(position);
ArrayList<String> urlImage = pullLinks(model.getContent());
String firstImage = "";
for (int i = 0; i < urlImage.size(); i++) {
firstImage = urlImage.get(1);
GlideCustomLoading.setImageFromURL(holder.itemView.getContext(), urlImage.get(0)
,holder.avLoadingIndicatorView, holder.ivItemPost,holder.tvFailedLoadImage);
}
holder.tvTitleItemPost.setText(model.getTitle());
final String finalFirstImage = firstImage;
holder.llItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String id = String.valueOf(model.getId());
DetailPostActivity.start(holder.itemView.getContext(), id, finalFirstImage, model.getTitle(), model.getUrl());
}
});
if(position>=getItemCount()-1){
load();
}
}
#Override
public int getItemCount() {
return responseBlogPost.size();
}
public class MainViewHolder extends RecyclerView.ViewHolder{
CardView cardViewItemPost;
ImageView ivItemPost;
TextView tvTitleItemPost;
AVLoadingIndicatorView avLoadingIndicatorView;
TextView tvFailedLoadImage;
LinearLayout llItem;
public MainViewHolder(View itemView) {
super(itemView);
cardViewItemPost = itemView.findViewById(R.id.cardview_item_post);
ivItemPost = itemView.findViewById(R.id.iv_image_post);
tvTitleItemPost = itemView.findViewById(R.id.tv_title_post);
avLoadingIndicatorView = itemView.findViewById(R.id.avi_load);
tvFailedLoadImage = itemView.findViewById(R.id.tv_gagal_menampilkan_gambar);
llItem = itemView.findViewById(R.id.ll_item_post);
}
}
private ArrayList pullLinks(String html) {
ArrayList links = new ArrayList();
Elements srcs = Jsoup.parse(html).select("[src]"); //get All tags containing "src"
for (int i = 0; i < srcs.size(); i++) {
links.add(srcs.get(i).attr("abs:src")); // get links of selected tags
}
return links;
}
}
While I'm not familiar with Jsoup I'm reasonably confident that it's the source of your scroll lag.
You are calling the method pullLinks in your onBindViewHolder method which is called every time a new view is added to your RecyclerView. I'm assuming pullLinks does some pretty intensive work that takes some time to complete.
What you would be better off doing is to add all of the data to each item in your responseBlogPost List before loading it in to the adapter.
I've a recyclerview adapter with 3 textviews. I used a model class to set texts. Now I want to use the same adapter with different layout and in a different class which only have 1 textview. When I tried, I got NullPointerException (may be becuz the other 2 textviews are blank). Is there any way to use same adapter with different layout and in different class?
// second class - I used 1 textview
public class Customers extends AppCompatActivity{
private CShowProgress cShowProgress;
private RecyclerView mRecyclerView;
private TimeLineAdapter mTimeLineAdapter;
private List<TimeLineModel> mDataList = new ArrayList<>();
private static final String CUSTOMERS = "http://192.168.200.3/ubooktoday/android/showspacustomerlist";
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.customers);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
cShowProgress = CShowProgress.getInstance();
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(getLinearLayoutManager());
mRecyclerView.setHasFixedSize(true);
showCustomers();
}
private void showCustomers() {
if(mDataList!=null )mDataList.clear();
cShowProgress.showProgress(Customers.this);
StringRequest stringRequest = new StringRequest(Request.Method.POST, CUSTOMERS,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
cShowProgress.hideProgress();
try {
JSONArray jsonArray = new JSONArray(response);
for(int i=0; i<jsonArray.length(); i++){
JSONObject obj = jsonArray.getJSONObject(i);
TimeLineModel model = new TimeLineModel();
model.setCustname(obj.getString("customername"));
mDataList.add(model);
mTimeLineAdapter = new TimeLineAdapter(getApplicationContext(), R.layout.item_row_customer, mDataList);
mRecyclerView.setAdapter(mTimeLineAdapter);
}
mTimeLineAdapter.notifyDataSetChanged();
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "VolleyError" + error.toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("spaid", "145");
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(stringRequest);
}
private LinearLayoutManager getLinearLayoutManager() {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
return linearLayoutManager;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
break;
}
return true;
}
}
// first class - I used all 3 textviews
public class Walkin extends Fragment{
private RecyclerView mRecyclerView;
private TimeLineAdapter mTimeLineAdapter;
private List<TimeLineModel> mDataList = new ArrayList<>();
private static final String DASHBOARD = "My API";
#Nullable
#Override
#Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.walkin, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(getLinearLayoutManager());
mRecyclerView.setHasFixedSize(true);
showDashboard();
}
private void showDashboard() {
if(mDataList!=null )mDataList.clear();
cShowProgress.showProgress(getActivity());
StringRequest stringRequest = new StringRequest(Request.Method.POST, DASHBOARD,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("walkinlist");
for(int i=0; i<jsonArray.length(); i++){
JSONObject obj = jsonArray.getJSONObject(i);
TimeLineModel model = new TimeLineModel();
model.setCustname(obj.getString("customername"));
model.setTime(obj.getString("serviceDuration"));
model.setServname(obj.getString("service"));
mDataList.add(model);
mTimeLineAdapter = new TimeLineAdapter(getActivity(), R.layout.item_row_dashboard, mDataList);
mRecyclerView.setAdapter(mTimeLineAdapter);
}
mTimeLineAdapter.notifyDataSetChanged();
} catch (JSONException e) {
// JSON error
e.printStackTrace();
Toast.makeText(getActivity(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), "VolleyError" + error.toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("spaid", "145");
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
requestQueue.add(stringRequest);
}
private LinearLayoutManager getLinearLayoutManager() {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
return linearLayoutManager;
}
}
// Adapter class
public class TimeLineAdapter extends RecyclerView.Adapter<TimeLineViewHolder> {
private List<TimeLineModel> mFeedList;
int resource;
private Context mContext;
public TimeLineAdapter(Context mContext, int resource, List<TimeLineModel> feedList) {
this.resource = resource;
this.mContext = mContext;
mFeedList = feedList;
}
#Override
public TimeLineViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = View.inflate(parent.getContext(), resource, null);
return new TimeLineViewHolder(view, viewType);
}
#Override
public void onBindViewHolder(TimeLineViewHolder holder, int position) {
TimeLineModel timeLineModel = mFeedList.get(position);
holder.servicename.setText(timeLineModel.getServname());
holder.custname.setText(timeLineModel.getCustname());
holder.time.setText(timeLineModel.getTime());
}
#Override
public int getItemCount() {
return (mFeedList!=null? mFeedList.size():0);
}
}
// ViewHolder class
public class TimeLineViewHolder extends RecyclerView.ViewHolder {
public TextView servicename, custname, time;
public TimeLineViewHolder(View itemView, int viewType) {
super(itemView);
servicename = (TextView) itemView.findViewById(R.id.tv_service);
custname = (TextView) itemView.findViewById(R.id.tv_cust);
time = (TextView) itemView.findViewById(R.id.tv_time);
}
}
You can use the getItemViewType().
Make your adapter(here TimeLineAdapter) extend RecyclerView.Adapter only.
You can change the Adapter's constructer to recieve ItemType and use it in the getItemViewType
Override the int getItemViewType (int position) method in your adapter.
In the onCreateViewHolder you can differentiate between which layout you want to inflate by using the viewType parameter.
In onBindViewHolder use instanceof to check which ViewHolder was created and call the related bind functions
A Sample Code-
// Adapter class
public class TimeLineAdapter extends RecyclerView.Adapter{
.....
int type;
public TimeLineAdapter(Context mContext, int resource, List<TimeLineModel> feedList,int layoutType) {
.....
.....
type=layoutType;
}
#Override
public int getItemViewType(int position) {
return type;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType==1){
View view = View.inflate(parent.getContext(), resource, null);
return new TimeLineViewHolder(view, viewType);
}else{
View view = View.inflate(parent.getContext(), resource, null);
return new TimeLineViewHolder2(view, viewType);
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(holder instanceof TimeLineViewHolder){
TimeLineModel timeLineModel = mFeedList.get(position);
((TimeLineViewHolder) holder).servicename.setText(timeLineModel.getServname());
......
}
else if(holder instanceof TimeLineViewHolder2){
....
....
}
}
#Override
public int getItemCount() {
return (mFeedList!=null? mFeedList.size():0);
}
}
when I conduct onRefresh, my recyclerView adds on another copy to my current recyclerView instead of refreshing it, by looking at my code below does anyone know what the problem is?I have tried everything but nothing seems to work?
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
//send our volley JSON Request
//Initialize VolleySingleton
mVolleySingleton = VolleySingleton.getInstance();
//intitalize Volley Singleton request key
mRequestQueue = mVolleySingleton.getRequestQueue();
//2 types of requests an Array request and an Object Request
JSONArrayRequest();
}
private void JSONArrayRequest() {
JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, URL_API, (String) null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
listblogs=parseJSONResponse(response);
mAdapterDashBoard.setBloglist(listblogs);
System.out.println("it worked!!!");
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
ToastTest.t(getActivity(), error.toString());
}
});
mRequestQueue.add(request);
}
private ArrayList<Blogs> parseJSONResponse(JSONArray response) {
if (!response.equals("")) {
ArrayList<Blogs> blogsArrayList = new ArrayList<>();
try {
StringBuilder data = new StringBuilder();
for (int i = 0; i < response.length(); i++) {
JSONObject currentQuestions = response.getJSONObject(i);
String text = currentQuestions.getString("text");
String points = currentQuestions.getString("points");
String ID=currentQuestions.getString("id");
String courseId = currentQuestions.getString("courseId");
String studentId = currentQuestions.getString("studentId");
data.append(text + "\n" + points + "\n" + courseId + "\n");
System.out.println(data);
Blogs blogs = new Blogs();
blogs.setId(ID);
blogs.setMstudentId(studentId);
blogs.setMtext(text);
blogs.setPoints(points);
listblogs.add(blogs);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return listblogs;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view=inflater.inflate(R.layout.fragment_dashboard,container,false);
mRecyclerView=(RecyclerView)view.findViewById(R.id.fragment_dashboard);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mAdapterDashBoard=new AdapterDashBoard(getActivity());
mRecyclerView.setAdapter(mAdapterDashBoard);
mPullToRefreshView = (PullToRefreshView)view.findViewById(R.id.pull_to_refresh);
mPullToRefreshView.setOnRefreshListener(new PullToRefreshView.OnRefreshListener() {
#Override
public void onRefresh() {
mPullToRefreshView.postDelayed(new Runnable() {
#Override
public void run() {
mPullToRefreshView.setRefreshing(false);
JSONArrayRequest();
}
}, REFRESH_DELAY);
}
});
return view;
}
}
public class AdapterDashBoard extends RecyclerView.Adapter<AdapterDashBoard.ViewDashboard>{
private LayoutInflater mLayoutInflater;
private ArrayList<Blogs> listblogs=new ArrayList<>();
public AdapterDashBoard(Context context){
mLayoutInflater=LayoutInflater.from(context);
}
public void setBloglist(ArrayList<Blogs> listBlogs){
this.listblogs=listBlogs;
notifyItemRangeChanged(0,listBlogs.size());
}
#Override
public ViewDashboard onCreateViewHolder(ViewGroup parent, int viewType) {
View view= mLayoutInflater.inflate(R.layout.customizejson,parent,false);
ViewDashboard viewholder=new ViewDashboard(view);
return viewholder;
}
#Override
public void onBindViewHolder(ViewDashboard holder, int position) {
Blogs currentBlog=listblogs.get(position);
holder.questionText.setText(currentBlog.getMtext().toString());
holder.points.setText(currentBlog.getPoints().toString());
holder.id.setText(currentBlog.getId().toString());
}
#Override
public int getItemCount() {
return listblogs.size();
}
static class ViewDashboard extends RecyclerView.ViewHolder{
private ImageView thumbnail;
private TextView questionText;
private TextView points;
private TextView id;
public ViewDashboard (View itemView){
super(itemView);
//thumbnail=(ImageView)itemView.findViewById(R.id.thumbnail);
questionText=(TextView)itemView.findViewById(R.id.questionText);
points=(TextView)itemView.findViewById(R.id.points);
id=(TextView)itemView.findViewById(R.id.ID);
}
}
}
You need to clear your listblogs list before adding new items. This is why you get duplicated values.
Also you're already adding new items to listblogs in parseJSONResponse() method, so there is no need for listblogs=parseJSONResponse(response); in onResponse() method, while its the same list.
Change your onResponse() method to:
#Override
public void onResponse(JSONArray response) {
listblogs.clear(); // here you clear the old data
parseJSONResponse(response);
mAdapterDashBoard.setBloglist(listblogs);
System.out.println("it worked!!!");
}