Reputation: 11
i have applied recyclerView in fragment in which i am showing product from api that is working fine. i have performed click listener on recyclerView, when i click the product and go to next fragment. But when i go to previous fragment that then my recycelerView loads data again and again. how i can avoid from this. i want to that it loads data once. here is my code xml code:
<android.support.v7.widget.RecyclerView
android:id="@+id/lsCategory"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginLeft="2dp"
android:layout_marginTop="4dp"
android:layout_marginRight="2dp"
android:background="@color/colorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
here is my recyclerView Code:
public class HomeFragment extends Fragment implements View.OnClickListener {
private List<Category> categories = new ArrayList<>();
private CategoryAdapter categoryAdapter;
public void getInfo(View view){
lsCategory = view.findViewById(R.id.lsCategory);
}
public void setInfo(){
getData();
}
public void getData(){
final StringRequest request = new StringRequest(Request.Method.GET, URLs.homeMainURL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
//categories
JSONArray categoryArray = jsonObject.getJSONArray("ListCategories");
setCategoryAdapter(categoryArray);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
VolleySingleton.getInstance(context).addToRequestQueue(request);
}
private void setCategoryAdapter(JSONArray array) {
try {
for (int i = 0; i < array.length(); i++) {
JSONObject object = array.getJSONObject(i);
final String name = object.getString("Name");
final int Id = object.getInt("ID");
categories.add(new Category(Id, name));
}
}catch(JSONException e) {
e.printStackTrace();
}
categoryAdapter = new CategoryAdapter(context, categories);
lsCategory.setLayoutManager(new LinearLayoutManager(context,LinearLayoutManager.HORIZONTAL,false));
lsCategory.setAdapter(categoryAdapter);
}
and here is my category Adapter
@Override
public void onBindViewHolder(@NonNull CategoryAdapter.ViewHolder holder, int position) {
holder.setData(categories.get(position));
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView textViewItemName;
private int Id ;
public ViewHolder(View itemView) {
super(itemView);
textViewItemName = itemView.findViewById(R.id.tvCategoris);
}
public void setData(final Category category){
textViewItemName.setText(category.getCategoryName());
Id = category.getId();
textViewItemName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ExpandableCategoryList fragment = new ExpandableCategoryList();
Bundle bundle = new Bundle();
bundle.putInt("Id",Id);
fragment.setArguments(bundle);
((MainActivity)context).replaceFragment(fragment,
"TAG",null,false);
}
});
}
}
Upvotes: 0
Views: 3340
Reputation: 141
Use fragmentTransaction.add(containerViewId, fragment, tag); instead of fragmentTransaction.replace(containerViewId, fragment, tag);
Difference between add and replace is:
replace removes the existing fragment and adds a new fragment. This means when you press back button the fragment that got replaced will be created with its onCreateView being invoked.
Whereas add retains the existing fragments and adds a new fragment that means existing fragment will be active and they wont be in 'paused' state hence when a back button is pressed onCreateView is not called for the existing fragment(the fragment which was there before new fragment was added).
In terms of fragment's life cycle events onPause, onResume, onCreateView and other life cycle events will be invoked in case of replace but they wont be invoked in case of add.
Upvotes: 1
Reputation: 92
There are two ways:
First :
if you are using replace then you should use addtobackstack(null) method with it as well. It would not call previous fragment onCreate method again when going back from next fragment to previous fragment. Make sure you are callling API in onCreate Method.
Second :
Try to read about setRetain(True) in fragments, Maybe it'll help you to stop loading fragment oncreate method again. Make sure you are callling API in onCreate Method.
Hope this helps. Happy Coding :)
Upvotes: 0
Reputation: 1219
I hope this will work for you.
Clear your arraylist before adding the data into it and add before try catch in your code. given like below and notify your adapter.
if(categories!=null){
categories.clear();
}
try {
for (int i = 0; i < array.length(); i++) {
JSONObject object = array.getJSONObject(i);
final String name = object.getString("Name");
final int Id = object.getInt("ID");
categories.add(new Category(Id, name));
}
}catch(JSONException e) {
e.printStackTrace();
}
categoryAdapter = new CategoryAdapter(context, categories);
rvCategory.setLayoutManager(new
LinearLayoutManager(context,LinearLayoutManager.HORIZONTAL,false));
rvCategory.setAdapter(categoryAdapter);
categoryAdapter.notifyDataSetChanged();
Upvotes: 2
Reputation: 105
Its a common problem faced by most of the android developers and can be solved by following methods.
1. Fist of all, clear the category object every time this fragment is loaded/called before adding data to it.
Example. category.clear(); if its a list
2. In your adapter, add this setHasStableIds(true); inside the constructor. It will stop duplicating the data in your list.
3. Override following methods in your adapter (IMP)
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public long getItemId(int position){
return position;
}
@Override
public int getItemCount() {
return category.size();
}
Let me know if it works!
Upvotes: 0