This question already has answers here:
How to update RecyclerView Adapter Data
(16 answers)
Closed 2 years ago.
I have tried most answers from this site without getting the desired result.
I have recyclerview with a list of items and a button contained in each row. When the button is clicked, I want the entire row to be deleted and list updated automatically.
Here's my adapter class code:
public class CartAdapter extends RecyclerView.Adapter<CartViewHolder> {
private static final String TAG = CartAdapter.class.getSimpleName();
private final Context context;
private List<Cart> itemsList;
private String id;
public CartAdapter(Context context, List<Cart> itemsList) {
this.context = context;
this.itemsList = itemsList;
}
#Override
public CartViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cart_items_layout, parent, false);
return new CartViewHolder(view);
}
#Override
public void onBindViewHolder(final CartViewHolder viewholder, final int position) {
final Cart cart = itemsList.get(position);
id = cart.getProductId();
AndroidNetworking.get(Constants.PRODUCT_DETAILS_ENDPOINT + id)
.setTag("Get Product Image")
.setPriority(Priority.HIGH)
.build()
.getAsJSONObject(new JSONObjectRequestListener() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, "Cart Item Image Response:\t" + response.toString());
String imagePath = null;
try {
JSONObject itemObject = new JSONObject(response.toString());
JSONObject data = itemObject.getJSONObject("data");
imagePath = data.getString("image");
Picasso.with(context)
.load(imagePath)
.placeholder(R.drawable.noimage)
.into(viewholder.cartItemImg);
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onError(ANError anError) {
}
});
viewholder.cartItemTitle.setText(cart.getProductTitle());
viewholder.cartQtyTV.setText(cart.getCartQty() + "");
viewholder.clearProductIV.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
removeProductRow(cart);
}
});
viewholder.decreaseCartIV.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
decreaseProduct();
}
});
viewholder.increaseCartIV.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
increaseProduct();
}
});
}
private void increaseProduct() {
}
private void decreaseProduct() {
}
public void removeProductRow(final Cart cart) {
AndroidNetworking.get(Constants.REMOVE_PRODUCT_CART + id)
.setTag("Delete Product From Cart")
.setPriority(Priority.HIGH)
.build()
.getAsJSONObject(new JSONObjectRequestListener() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, "Delete Product From Cart Response:\t" + response.toString());
int position = itemsList.indexOf(cart);
itemsList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, itemsList.size());
}
#Override
public void onError(ANError anError) {
}
});
}
#Override
public int getItemCount() {
if (itemsList == null) {
return 0;
}
return itemsList.size();
}
}
This code works and the item is deleted. However, the list does not update until I re-visit the activity again. How can I update the view immediately?
private update(Cart cart){
Log.d(TAG, "Delete Product From Cart Response:\t" +
response.toString());
int position = itemsList.indexOf(cart);
itemsList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, itemsList.size());
}
And then, onResponse just call update(cart); <- You may need to pass some other data into this function based on your needs.
Update (related to your second problem):
#Override
public long getItemId(int position) {
return itemList != null ? itemList.get(position).getId() : 0;
}
Or, you could make a public function that return the full item for you
public Cart getItem(int position){
return itemList != null itemList.get(position) : null;
} // you have to check if this is null when you call it
maybe not UI thread running below codeļ¼cause not timely refresh interface
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, "Delete Product From Cart Response:\t" + response.toString());
int position = itemsList.indexOf(cart);
itemsList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, itemsList.size());
}
Related
Hi in the below code I am getting the below error for displaying a list using recyclerview .
When I am trying to display the list I am getting the below error.
java.lang.ClassCastException: java.lang.String cannot be cast to helper.GetBuildingList
at com.deepshikha.lightingsystem.SwipeRecyclerViewAdapter.onBindViewHolder(SwipeRecyclerViewAdapter.java:41)
at com.deepshikha.lightingsystem.SwipeRecyclerViewAdapter.onBindViewHolder(SwipeRecyclerViewAdapter.java:22)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6781)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6823)
Response :
[{"ID":"1","Name":"Building1"},{"ID":"2","Name":"appexx"}]
In the below adapter displays the what are the item presents in the getbuildinglist pojo class.As well as Once user swiped from right to left .We are displaying two options for the list items to edit and delete the items.
SwipeAdapter:
public class SwipeRecyclerViewAdapter extends RecyclerSwipeAdapter<SwipeRecyclerViewAdapter.SimpleViewHolder> {
private Context mContext;
private List<GetBuildingList> buildingLists;
public SwipeRecyclerViewAdapter(Context context, List<GetBuildingList> strings) {
this.mContext = context;
this.buildingLists = strings;
}
#Override
public SimpleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item, parent, false);
return new SimpleViewHolder(view);
}
#Override
public void onBindViewHolder(final SimpleViewHolder viewHolder, final int position) {
final GetBuildingList item = buildingLists.get(position);
System.out.println ("item"+item);
viewHolder.tvName.setText((item.getName ()) + " - Row Position " + position);
System.out.println (item.getName ());
viewHolder.swipeLayout.setShowMode(SwipeLayout.ShowMode.PullOut);
// Drag From Left
// viewHolder.swipeLayout.addDrag(SwipeLayout.DragEdge.Left, viewHolder.swipeLayout.findViewById(R.id.bottom_wrapper1));
// Drag From Right
viewHolder.swipeLayout.addDrag(SwipeLayout.DragEdge.Right, viewHolder.swipeLayout.findViewById(R.id.bottom_wrapper));
// Handling different events when swiping
viewHolder.swipeLayout.addSwipeListener(new SwipeLayout.SwipeListener() {
#Override
public void onClose(SwipeLayout layout) {
//when the SurfaceView totally cover the BottomView.
}
#Override
public void onUpdate(SwipeLayout layout, int leftOffset, int topOffset) {
//you are swiping.
}
#Override
public void onStartOpen(SwipeLayout layout) {
}
#Override
public void onOpen(SwipeLayout layout) {
//when the BottomView totally show.
}
#Override
public void onStartClose(SwipeLayout layout) {
}
#Override
public void onHandRelease(SwipeLayout layout, float xvel, float yvel) {
//when user's hand released.
}
});
/*viewHolder.swipeLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if ((((SwipeLayout) v).getOpenStatus() == SwipeLayout.Status.Close)) {
//Start your activity
Toast.makeText(mContext, " onClick : " + item.getName() + " \n" + item.getEmailId(), Toast.LENGTH_SHORT).show();
}
}
});*/
viewHolder.swipeLayout.getSurfaceView().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, " onClick : " + item.getName () + " \n" + item.getID (), Toast.LENGTH_SHORT).show();
}
});
// viewHolder.btnLocation.setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View v) {
//
// Toast.makeText(v.getContext(), "Clicked on Map " + viewHolder.tvName.getText().toString(), Toast.LENGTH_SHORT).show();
// }
// });
//
//
// viewHolder.tvShare.setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View view) {
//
// Toast.makeText(view.getContext(), "Clicked on Share " + viewHolder.tvName.getText().toString(), Toast.LENGTH_SHORT).show();
// }
// });
viewHolder.tvEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "Clicked on Edit " + viewHolder.tvName.getText().toString(), Toast.LENGTH_SHORT).show();
}
});
viewHolder.tvDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mItemManger.removeShownLayouts(viewHolder.swipeLayout);
buildingLists.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, buildingLists.size());
mItemManger.closeAllItems();
Toast.makeText(view.getContext(), "Deleted " + viewHolder.tvName.getText().toString(), Toast.LENGTH_SHORT).show();
}
});
// mItemManger is member in RecyclerSwipeAdapter Class
mItemManger.bindView(viewHolder.itemView, position);
}
#Override
public int getItemCount() {
return buildingLists.size();
}
#Override
public int getSwipeLayoutResourceId(int position) {
return R.id.swipe;
}
// ViewHolder Class
public static class SimpleViewHolder extends RecyclerView.ViewHolder {
SwipeLayout swipeLayout;
TextView tvName;
TextView tvDelete;
TextView tvEdit;
public SimpleViewHolder(View itemView) {
super(itemView);
swipeLayout = (SwipeLayout) itemView.findViewById(R.id.swipe);
tvName = (TextView) itemView.findViewById(R.id.tvName);
// tvEmailId = (TextView) itemView.findViewById(R.id.tvEmailId);
tvDelete = (TextView) itemView.findViewById(R.id.tvDelete);
tvEdit = (TextView) itemView.findViewById(R.id.tvEdit);
// tvShare = (TextView) itemView.findViewById(R.id.tvShare);
// btnLocation = (ImageButton) itemView.findViewById(R.id.btnLocation);
}
}
}
In the below code describes the without refreshing the activity I am getting the response from the server.
That response I am adding to arraylist then setting the adapter to the recyclerview to display the list of items with swipe options.
Add.java:
private void doTheAutoRefresh() {
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Write code for your refresh logic
progressDialog = new ProgressDialog (getActivity ());
progressDialog.setIndeterminate(true);
progressDialog.setMessage("Communicating...");
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
progressDialog.show();
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API.URL_BASE)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client (client)
.build();
API service = retrofit.create (API.class);
Call<List<GetBuildingList>> userCall = service.getbuildinglist ();
userCall.enqueue(new Callback<List<GetBuildingList>> () {
#Override
public void onResponse(Call <List<GetBuildingList>> call, Response <List<GetBuildingList>> response) {
if(response.isSuccessful()) {
progressDialog.dismiss ( );
Log.d ("Response body", new Gson ( ).toJson (response.body ( )));
String Status = new Gson ( ).toJson (response.body ( ));
JSONArray jsonArray = null;
try {
JSONObject jsonObject=null;
jsonArray = new JSONArray (Status);
arrayList = new ArrayList <> ( );
for (int i=0;i<jsonArray.length ();i++) {
name=jsonArray.getJSONObject (i).getString ("Name");
arrayList.add (name);
}
// Creating Adapter object
SwipeRecyclerViewAdapter mAdapter = new SwipeRecyclerViewAdapter((Context) getActivity (), arrayList);
mAdapter.notifyDataSetChanged ();
mRecyclerView.setAdapter(mAdapter);
} catch (JSONException e) {
e.printStackTrace ( );
}
}
else {
progressDialog.dismiss ();
Log.d("Response errorBody", String.valueOf(response.errorBody()));
}
}
#Override
public void onFailure(Call<List<GetBuildingList>> call, Throwable t) {
// lv.setAdapter (adapter);
System.out.println("onFailure");
System.out.println(t.fillInStackTrace());
progressDialog.dismiss();
Toast.makeText(getActivity (), "Some error occurred -> ", Toast.LENGTH_LONG).show();;
// progressDialog.dismiss();
}
});
}
}, 5000);
return ;
}
GetBuildingList.java:
public class GetBuildingList{
#SerializedName("ID")
private String ID;
#SerializedName("Name")
private String Name;
public String getID() {
return ID;
}
public void setID(String ID) {
this.ID = ID;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
}
In your onResponse() method you have these lines:
name=jsonArray.getJSONObject (i).getString ("Name");
...
arrayList.add (name);
Then you pass this list to your adapter. This list is assigned to the GetBuildingList field of your adapter. Then in your adapter you do:
final GetBuildingList item = buildingLists.get(position);
So you're trying to cast String type to GetBuildingList type, hence the exception.
Not really familiar with the library but you should try something like this:
for (int i=0;i<jsonArray.length ();i++) {
String name = jsonArray.getJSONObject (i).getString ("Name");
String id = jsonArray.getJSONObject (i).getString ("Id");
GetBuildingList gbl = new GetBuildingList();
gbl.setId(id);
gbl.setName(name);
arrayList.add(gbl);
}
I haven't used this library yet so if I'm wrong, someone please correct the above sample.
In my project, there is need of searching data from server using keyword. After search, i am displaying results using RecyclerView . While searching fast, the data in RecyclerView is duplicating. If searching slowly, it's working fine. Any suggestions are appreciated. Thank you.
The below code for making server call:
private void callSearchUserApi(final String searchText, int currentPage, boolean clearData) {
isApiCallInProcess = true;
String URL = "userinfo/api/v1/user-search/" + "?page=" + currentPage;
if (!Connectivity.isConnected(activity)) {
Common.snackBarNoConnection(activity, activity.getString(R.string.no_conection));
//setOnProgressbarVisibility(View.GONE);
return;
}
if (clearData) {
globalSearchUsersModelList.clear();
//BS globalSearchUserResultsAdapter.notifyDataSetChanged();
}
ApiInterface apiCall = ApiClient.getApiService(activity);
final Call<SearchUsersModel> globalUserSearchApiCall = apiCall.searchUser(
URL,
searchText);
globalUserSearchApiCall.enqueue(new Callback<SearchUsersModel>() {
#Override
public void onResponse(Call<SearchUsersModel> call, Response<SearchUsersModel> response) {
if (response.isSuccessful() && response.body().getStatus().equalsIgnoreCase(Common.SUCCESS_RESPONSE)) {
//BS globalSearchUsersModelList.addAll(response.body().getData().getData());
for (int i = 0; i < response.body().getData().getData().size(); i++) {
SearchUsersModel.DataBeanX.DataBean dataBean = new SearchUsersModel.DataBeanX.DataBean();
dataBean.setDesignation(response.body().getData().getData().get(i).getDesignation());
dataBean.setFull_name(response.body().getData().getData().get(i).getFull_name());
dataBean.setGender(response.body().getData().getData().get(i).getGender());
dataBean.setId(response.body().getData().getData().get(i).getId());
dataBean.setPlace(response.body().getData().getData().get(i).getPlace());
dataBean.setProfile_pic(response.body().getData().getData().get(i).getProfile_pic());
globalSearchUsersModelList.add(dataBean);
/*BS if (!globalSearchUsersModelList.contains(response.body().getData().getData().get(i)))
globalSearchUsersModelList.add(response.body().getData().getData().get(i));*/
}
CURRENT_PAGE = response.body().getData().getPage();
isLoading = false;
if (response.body().getData().isNext() == false)
isLastPage = true;
else
isLastPage = false;
if (globalSearchUsersModelList.size() == 0) {
rv_GlobalsearchList.setVisibility(View.GONE);
rl_placeholderGSPeople.setVisibility(View.VISIBLE);
tv_placeholderGSPeople.setText(activity.getString(R.string.no_search_found) + " " + searchText);
} else {
rv_GlobalsearchList.setVisibility(View.VISIBLE);
rl_placeholderGSPeople.setVisibility(View.GONE);
}
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
globalSearchUserResultsAdapter.notifyDataSetChanged();
}
});
}
if (searchTextsList.size() > 0) {
String sText = searchTextsList.get(0);
searchTextsList.remove(0);
callSearchUserApi(sText, FIRST_PAGE, true);
} else
isApiCallInProcess = false;
}
#Override
public void onFailure(Call<SearchUsersModel> call, Throwable t) {
isApiCallInProcess = false;
}
});
}
This is my Adapter.
public class GlobalSearchUserResultsAdapter extends RecyclerView.Adapter<GlobalSearchUserResultsAdapter.SearchViewHolder> {
private Context context;
private List<SearchUsersModel.DataBeanX.DataBean> searchUserList;
public GlobalSearchUserResultsAdapter(Context context, List<SearchUsersModel.DataBeanX.DataBean> searchUserList){
this.context = context;
this.searchUserList = searchUserList;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public SearchViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.v("Search", "Adapter Activity : "+context);
View view = LayoutInflater.from(context).inflate(R.layout.global_search_row, parent, false);
return new GlobalSearchUserResultsAdapter.SearchViewHolder(view);
}
#Override
public void onBindViewHolder(GlobalSearchUserResultsAdapter.SearchViewHolder holder, int position) {
if ( searchUserList.get(position).getGender().equals("M")) {
holder.iv_userImage.setBackgroundResource(R.drawable.white_border_with_circle_appblue);
Common.setGlideImage((GlobalSearchActivity)context,
holder.iv_userImage,
/*searchUsersModel*/searchUserList.get(position).getProfile_pic(),
R.drawable.male,
true);
} else if (searchUserList.get(position).getGender().equals("F")) {
holder.iv_userImage.setBackgroundResource(R.drawable.white_border_with_circle_pink);
Common.setGlideImage((GlobalSearchActivity)context,
holder.iv_userImage,
searchUserList.get(position).getProfile_pic(),
R.drawable.female,
true);
} else {
Common.setGlideImage((GlobalSearchActivity)context,
holder.iv_userImage,
searchUserList.get(position).getProfile_pic(),
R.drawable.deafult_profilepic,
true);
}
holder.tv_userName.setText(searchUserList.get(position).getFull_name());
holder.tv_userName.setTypeface(Common
.getFontTypeface(context, GlobalConstants.FONT_AVENIR_MEDIUM));
holder.tv_place.setText(searchUserList.get(position).getPlace());
holder.tv_place.setTypeface(Common
.getFontTypeface(context, GlobalConstants.FONT_AVENIR_MEDIUM));
holder.designation.setText(searchUserList.get(position).getDesignation());
}
#Override
public int getItemCount() {
return searchUserList.size();
}
public class SearchViewHolder extends RecyclerView.ViewHolder{
private ImageView iv_userImage;
private TextView tv_userName;
private TextView tv_place;
private TextView designation;
public SearchViewHolder(View itemView) {
super(itemView);
this.iv_userImage = (ImageView) itemView.findViewById(R.id.imageSearch);
this.tv_userName = (TextView) itemView.findViewById(R.id.nameSearch);
tv_userName.setTypeface(Common.getFontTypeface(context,
GlobalConstants.FONT_AVENIR_MEDIUM));
this.designation = (TextView) itemView.findViewById(R.id.designation);
designation.setTypeface(Common.getFontTypeface(context,
GlobalConstants.FONT_AVENIR_MEDIUM));
this.tv_place = (TextView) itemView.findViewById(R.id.placeSearch);
tv_place.setTypeface(Common.getFontTypeface(context,
GlobalConstants.FONT_AVENIR_LIGHT));
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
context.startActivity(new Intent(context, ProfileActivity.class)//ThirdParty
.putExtra(GlobalConstants.KEY_THIRD_PARTY_ID, searchUserList.get(getAdapterPosition()).getId()));
}
});
}
}
}
You just had to clear the globalSearchUsersModelList list just before for loop, because API call is asynchronous.
globalSearchUsersModelList.clear();// Important one
for (int i = 0; i < response.body().getData().getData().size(); i++) {
// do your stuff
}
I think the issue come from your getItemId implementation. The way you implement it, the recycler view will identify an item according to its position in the list.
If you change this and use unique identification for instance searchUserList.get(position).id (if your User object has an unique ID) the problem should be fixed
You can also add in your activity adapter.setHasStableIds(true)
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 am trying to call local API server using retrofit, in my Logcat shows that the API success called, but in my app there is nothing displayed. how i can fix this issue? and here is my code :
interface.java :
public interface Service {
#GET("vocabulary/id/*")
Call<APIResponse<List<VocabMaster>>> getVocabMaster();
}
Vocab Master.java to collect data from API :
public class VocabMaster implements Serializable {
private BigDecimal vocab_id;
private String hanzi_t;
private String hanzi_s;
private String pinyin;
private BigDecimal level_id;
private List<VocabMeaning> meaning;
public BigDecimal getVocab_id() {
return vocab_id;
}
public void setVocab_id(BigDecimal vocab_id) {
this.vocab_id = vocab_id;
}
public String getHanzi_t() {
return hanzi_t;
}
public void setHanzi_t(String hanzi_t) {
this.hanzi_t = hanzi_t;
}
public String getHanzi_s() {
return hanzi_s;
}
public void setHanzi_s(String hanzi_s) {
this.hanzi_s = hanzi_s;
}
public String getPinyin() {
return pinyin;
}
public void setPinyin(String pinyin) {
this.pinyin = pinyin;
}
public List<VocabMeaning> getMeaning() {
return meaning;
}
public void setMeaning(List<VocabMeaning> meaning) {
this.meaning = meaning;
}
public BigDecimal getLevel_id() {
return level_id;
}
public void setLevel_id(BigDecimal level_id) {
this.level_id = level_id;
}
#Override
public String toString() {
return "VocabMaster{" +
"vocab_id=" + vocab_id +
", hanzi_t='" + hanzi_t + '\'' +
", hanzi_s='" + hanzi_s + '\'' +
", pinyin='" + pinyin + '\'' +
", level_id=" + level_id +
", meaning=" + meaning +
'}';
}
}
And this is MainActivity.java :
public class MainActivity extends AppCompatActivity {
RecyclerView rvReligiVideo;
List<VocabMaster> vocabMasters = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rvReligiVideo = findViewById(R.id.rvReligi);
initReligiVideo();
loadReligiVideo();
}
private void initReligiVideo() {
LinearLayoutManager layout = new LinearLayoutManager(this);
layout.setOrientation(LinearLayoutManager.HORIZONTAL);
rvReligiVideo.setLayoutManager(layout);
VocabAdapter ar = new VocabAdapter(vocabMasters);
rvReligiVideo.setAdapter(ar);
}
//=========== Request to API ==========
private void loadReligiVideo() {
Call<APIResponse<List<VocabMaster>>> call = ServicesFactory.getService().getVocabMaster();
call.enqueue(new Callback<APIResponse<List<VocabMaster>>>() {
#Override
public void onResponse(Call<APIResponse<List<VocabMaster>>> call, Response<APIResponse<List<VocabMaster>>> response) {
if (response.isSuccessful() && response.body().isSuccessful()) {
List<VocabMaster> data = response.body().data;
if (data != null) {
vocabMasters.clear();
vocabMasters.addAll(data);
rvReligiVideo.getAdapter().notifyDataSetChanged();
}
} else {
Toast.makeText(MainActivity.this, response.errorBody().toString(), Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<APIResponse<List<VocabMaster>>> call, Throwable t) {
Toast.makeText(MainActivity.this, t.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
});
}
}
logcat on android studio :
JSON Data Structure :
Here is my Adapter :
public class VocabAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
List<VocabMaster> data;
public VocabAdapter(List<VocabMaster> data) {
this.data = data;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.vocabulary_model, null);
return new VH(v);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
VocabMaster vm = data.get(position);
VH vh = (VH) holder;
vh.hanziS.setText(vm.getHanzi_s());
vh.hanziT.setText(vm.getHanzi_t());
vh.pinyin.setText(vm.getPinyin());
vh.sound.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Sound", Toast.LENGTH_SHORT).show();
}
});
vh.favorite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Favorite", Toast.LENGTH_SHORT).show();
}
});
vh.share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Share", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return (data == null) ? 0 : data.size();
}
public class VH extends RecyclerView.ViewHolder {
TextView hanziS;
TextView hanziT;
TextView pinyin;
TextView desc;
ImageView sound, share, favorite;
Context context;
public VH(View itemView) {
super(itemView);
hanziS = itemView.findViewById(R.id.hanziS);
hanziT = itemView.findViewById(R.id.hanziT);
pinyin = itemView.findViewById(R.id.pinyin);
desc = itemView.findViewById(R.id.txtDesc);
sound = itemView.findViewById(R.id.imgSpeaker);
share = itemView.findViewById(R.id.imgShare);
favorite = itemView.findViewById(R.id.imgFavotite);
}
}
}
i did some changes in your code... use this
private VocabAdapter ar;
private void initReligiVideo() {
LinearLayoutManager layout = new LinearLayoutManager(this);
layout.setOrientation(LinearLayoutManager.HORIZONTAL);
rvReligiVideo.setLayoutManager(layout);
ar = new VocabAdapter(vocabMasters);
rvReligiVideo.setAdapter(ar);
}
private void loadReligiVideo() {
Call<APIResponse<List<VocabMaster>>> call = ServicesFactory.getService().getVocabMaster();
call.enqueue(new Callback<APIResponse<List<VocabMaster>>>() {
#Override
public void onResponse(Call<APIResponse<List<VocabMaster>>> call, Response<APIResponse<List<VocabMaster>>> response) {
if (response.isSuccessful() && response.body().isSuccessful()) {
List<VocabMaster> data = response.body().data;
if (data != null) {
ar.setVocoList(data);
}
} else {
Toast.makeText(MainActivity.this, response.errorBody().toString(), Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<APIResponse<List<VocabMaster>>> call, Throwable t) {
Toast.makeText(MainActivity.this, t.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
});
}
Add this method in your adapter Class
public void setVocoList(List<VocabMaster> list){
if(list!=null)
data=list;
notifyDataSetChanged();
}
Do not change adapter's list when you have new list.
//incorrect except that the adapter is first time set to recyclerview and setVocoList is called before recyclerview.setAdater
public void setVocoList(List<VocabMaster> list){
if(list!=null)
data=list;
notifyDataSetChanged();
}
//correct
private List<VocabMaster> datas = new ArrayList()
public void setVocoList(List<VocabMaster> list){
if(list==null) return;
datas.clear();
datas.addAll(list);
notifyDataSetChanged();
}
I want to fetch data from api using retrofit in recycler view im showing only shop name and timings when i click on the item in other activty i have to show the complete details of the shop for that i want position variable to fetch data of the position i selected
#Override
public void onBindViewHolder(final MyViewHolder holder, final int listPosition) {
TextView textViewName = holder.textViewName;
TextView textViewVersion = holder.textViewTime;
textViewName.setText(dataSet.get(listPosition).getShop_name());
textViewVersion.setText(dataSet.get(listPosition).getShop_time());
}
private class MyOnClickListener implements View.OnClickListener {
private final Context context;
private MyOnClickListener(Context context) {
this.context = context;
}
#Override
public void onClick(View v) {
Intent intent=new Intent(MainActivity.this,ViewMoreActivity.class);
startActivity(intent);
}
}
public void fetchingData()
{
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Please Wait..");
progressDialog.setCancelable(false);
progressDialog.show();
Retrofit adapter = new Retrofit.Builder()
.baseUrl(Constandapi.ROOT_URL)
.build();
ShopDetailsInterface report = adapter.create(ShopDetailsInterface.class);
Call<ResponseBody> post_register;
post_register = report.post_register("gow#gmail.com",
"202cb962ac59075b964b07152d234b70","tw_puncture");
post_register.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
String result = response.body().string();
Log.d("resultdisplayLogin", "*** " + result);
JSONArray jsonArray=new JSONArray(result);
for(int i=0;i<jsonArray.length();i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
DataModel dataModel = new DataModel();
dataModel.setShop_name(jsonObject.getString("shop_name"));
dataModel.setShop_time(jsonObject.getString("shop_time"));
data.add(dataModel);
progressDialog.dismiss();
Log.d("datafetched", data+"");
}
detailadapter.notifyDataSetChanged();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}else
{
progressDialog.dismiss();
Toast.makeText(getApplicationContext(),"try Again........",Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
how to access the position variable of onbindviewholder() adapter class in other activity
Assuming you Recyclerview has a viewHolder MyViewHolder
class MyViewHolder extends ViewHolder implements View.OnClickListener {
// Assuming your row layout is having parent having id parent
public MyViewHolder (View v) {
super(v);
parent = v.findViewByID(R.id.parentID);
parent.setOnClickListener(this);
}
#Override
public void OnClick(View v) {
int position = getAdapterPosition(); // Use this position
}
}
Use an interface. It should contain a method like void onItemClick(int position);