I have a fragment with a recyclerView.
A user is allowed to delete an exercise logEntry by swiping right.
A user can also update a logEntry by clicking on the recyclerView item.
(This highlights the current selected item green, hides the clear button and converts the save button to an update button.)
To deselect the item , the user can click on the recyclerView a second time.
Unfortunately, if a user was to select an item and then decides to swipe to delete an item, the recyclerView item which takes the same position as the originally selected item is remains highlighted green.
When a user swipes to delete an item, I would like the background of all recyclerView items to be reset to grey.
How could this be done?
Relevant Fragment Code
OnExerciseClicked
#Override
public void onExerciseClicked(int position) {
if (recyclerItemClicked == false) {
saveBtn.setText("Update");
clearBtn.setVisibility(View.GONE);
recyclerItemClicked = true;
double selectedWeight = adapter.getWeight(position);
String selectedWeightString = Double.toString(selectedWeight);
editTextWeight.setText(selectedWeightString);
int selectedReps = adapter.getReps(position);
String selectedRepsString = Integer.toString(selectedReps);
editTextReps.setText(selectedRepsString);
} else {
clearBtn.setVisibility(View.VISIBLE);
saveBtn.setText("Save");
recyclerItemClicked = false;
}
}
OnSwiped
ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
int logID = allExercises.get(viewHolder.getAdapterPosition()).getLog_id();
logViewModel.deleteByID(logID);
clearBtn.setVisibility(View.VISIBLE);
saveBtn.setText("Save");
adapter.notifyDataSetChanged();
}
};
Adapter
public class CompletedExercisesListAdapter2 extends RecyclerView.Adapter {
private OnExerciseClickListener onExerciseClickListener;
private List<Log_Entries> allCompletedExercises = new ArrayList<>();
private int adapterPos = -1;
public boolean flag = false;
public CompletedExercisesListAdapter2(ArrayList<Log_Entries> allCompletedExercises, OnExerciseClickListener onExerciseClickListener) {
this.allCompletedExercises = allCompletedExercises;
this.onExerciseClickListener = onExerciseClickListener;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view;
if (viewType == 0) {
view = layoutInflater.inflate(R.layout.new_completed_exercise_item, parent, false);
return new ViewHolderOne(view, onExerciseClickListener);
}
view = layoutInflater.inflate(R.layout.completed_exercise_item, parent, false);
return new ViewHolderTwo(view, onExerciseClickListener);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
if (getItemViewType(position) == 0) {
ViewHolderOne viewHolderOne = (ViewHolderOne) holder;
if (adapterPos == position) {
viewHolderOne.relativeLayout.setBackgroundColor(Color.parseColor("#567845"));
} else {
viewHolderOne.relativeLayout.setBackgroundResource(R.color.dark_grey);
}
viewHolderOne.textViewExerciseName.setText(String.valueOf(allCompletedExercises.get(position).getChildExerciseName()));
//viewHolderOne.textViewSetNumber.setText(String.valueOf(allCompletedExercises.get(position).getSet_number()));
viewHolderOne.textViewSetNumber.setText(String.valueOf(viewHolderOne.getAdapterPosition() + 1));
viewHolderOne.textViewWeight.setText(String.valueOf(allCompletedExercises.get(position).getTotal_weight_lifted()));
viewHolderOne.textViewReps.setText(String.valueOf(allCompletedExercises.get(position).getReps()));
} else if (getItemViewType(position) == 1) {
ViewHolderTwo viewHolderTwo = (ViewHolderTwo) holder;
if (adapterPos == position) {
viewHolderTwo.relativeLayout.setBackgroundColor(Color.parseColor("#567845"));
} else {
viewHolderTwo.relativeLayout.setBackgroundResource(R.color.dark_grey);
}
// viewHolderTwo.textViewSetNumber.setText(String.valueOf(allCompletedExercises.get(position).getSet_number()));
viewHolderTwo.textViewSetNumber.setText(String.valueOf(viewHolderTwo.getAdapterPosition() + 1));
viewHolderTwo.textViewWeight.setText(String.valueOf(allCompletedExercises.get(position).getTotal_weight_lifted()));
viewHolderTwo.textViewReps.setText(String.valueOf(allCompletedExercises.get(position).getReps()));
}
}
#Override
public int getItemCount() {
return allCompletedExercises.size();
}
#Override
public int getItemViewType(int position) {
// if list is sorted chronologically
if (position == 0) {
return 0;
}
if (allCompletedExercises.get(position).getChildExerciseName().equals(allCompletedExercises.get(position - 1).getChildExerciseName())) {
return 1;
} else {
return 0;
}
}
class ViewHolderOne extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView textViewExerciseName;
private TextView textViewSetNumber;
private TextView textViewWeight;
private TextView textViewReps;
OnExerciseClickListener mOnExerciseClickListener;
private RelativeLayout relativeLayout;
public ViewHolderOne(#NonNull View itemView, OnExerciseClickListener onExerciseClickListener) {
super(itemView);
textViewExerciseName = itemView.findViewById(R.id.textView_ExerciseName3);
textViewSetNumber = itemView.findViewById(R.id.textView_Set_Number56);
textViewWeight = itemView.findViewById(R.id.textView_weight78);
textViewReps = itemView.findViewById(R.id.textView_repss0);
mOnExerciseClickListener = onExerciseClickListener;
relativeLayout = (RelativeLayout) itemView.findViewById(R.id.exercise_item_relative);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
onExerciseClickListener.onExerciseClicked(getAdapterPosition());
if (flag) {
adapterPos = -1;
flag = false;
} else {
adapterPos = getAdapterPosition();
flag = true;
}
notifyDataSetChanged();
}
}
class ViewHolderTwo extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView textViewSetNumber;
private TextView textViewWeight;
private TextView textViewReps;
OnExerciseClickListener mOnExerciseClickListener;
private RelativeLayout relativeLayout;
public ViewHolderTwo(#NonNull View itemView, OnExerciseClickListener onExerciseClickListener) {
super(itemView);
textViewSetNumber = itemView.findViewById(R.id.textView_Set_Number);
textViewWeight = itemView.findViewById(R.id.textView_weight);
textViewReps = itemView.findViewById(R.id.textView_repss);
relativeLayout = (RelativeLayout) itemView.findViewById(R.id.exercise_item_rel);
mOnExerciseClickListener = onExerciseClickListener;
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
onExerciseClickListener.onExerciseClicked(getAdapterPosition());
if (!flag) {
adapterPos = getAdapterPosition();
flag = true;
} else {
adapterPos = -1;
flag = false;
}
notifyDataSetChanged();
}
}
public interface OnExerciseClickListener {
void onExerciseClicked(int position);
}
public double getWeight(int position) {
double weight = allCompletedExercises.get(position).getTotal_weight_lifted();
return weight;
}
public int getReps(int position) {
int reps = allCompletedExercises.get(position).getReps();
return reps;
}
}
I highly recommend using a library like Groupie to abstract away the complicated state management of RecyclerView. Otherwise you'll find this imperative style quickly becomes unmaintainable. The future is declarative UI (Compose etc). This way it is much easier to keep track of Items rather than positions.
It's quite hard to follow your code (you should use descriptive names for things, like isSelected instead of flag). However I think your problem lies in your bind function not returning false here:
if (adapterPos == position)
after you swipe. Use break points to work out why
Related
UPDATE When I Log.i("adapterPos", String.valueOf(adapter.adapterPos)); in onSwiped, it returns -1 even before setting it to -1...
I have a recyclerView, as well as a custom adapter to display information about an exercise.
When a user taps on a recyclerView item, the items background is set to green, and the save button turns into an update button, so that the user can update their existing recorded exercises.
I also have an onSwiped method which is implemented inside my fragment. When a user swipes an item, it is deleted from the database.
When a user swipes to delete an item, I would like to set the background for ALL items back to the default (grey).
How could this be done?
Note: if item 2 is selected and the user decides to swipe item 1, even after item 1 is deleted, item 2 is still currently selected.
Record Exercise Fragment (Relevant code)
#Override
public void onExerciseClicked(int position) {
if (recyclerItemClicked == false) {
saveBtn.setText("Update");
clearBtn.setVisibility(View.GONE);
recyclerItemClicked = true;
double selectedWeight = adapter.getWeight(position);
String selectedWeightString = Double.toString(selectedWeight);
editTextWeight.setText(selectedWeightString);
int selectedReps = adapter.getReps(position);
String selectedRepsString = Integer.toString(selectedReps);
editTextReps.setText(selectedRepsString);
} else {
clearBtn.setVisibility(View.VISIBLE);
saveBtn.setText("Save");
recyclerItemClicked = false;
}
}
public void initRecyclerView() {
adapter = new CompletedExercisesListAdapter2(allExercises, this);
recyclerView.setAdapter(adapter);
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);
}
public void setExercises(List<Log_Entries> exercises) {
allExercises.clear();
allExercises.addAll(exercises);
}
ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
int logID = allExercises.get(viewHolder.getAdapterPosition()).getLog_id();
logViewModel.deleteByID(logID);
clearBtn.setVisibility(View.VISIBLE);
saveBtn.setText("Save");
Log.i("adapterPos", String.valueOf(adapter.adapterPos)); // this is always -1 for some reason
// backup the currently selected position
int selectedPos = adapter.adapterPos;
// change the currently selected position to -1
adapter.adapterPos = -1;
adapter.notifyItemChanged(selectedPos);
}
};
Adapter
public class CompletedExercisesListAdapter2 extends RecyclerView.Adapter {
private OnExerciseClickListener onExerciseClickListener;
private List<Log_Entries> allCompletedExercises = new ArrayList<>();
public int adapterPos = -1;
public boolean isSelected = false;
public CompletedExercisesListAdapter2(ArrayList<Log_Entries> allCompletedExercises, OnExerciseClickListener onExerciseClickListener) {
this.allCompletedExercises = allCompletedExercises;
this.onExerciseClickListener = onExerciseClickListener;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view;
if (viewType == 0) {
view = layoutInflater.inflate(R.layout.new_completed_exercise_item, parent, false);
return new ViewHolderOne(view, onExerciseClickListener);
}
view = layoutInflater.inflate(R.layout.completed_exercise_item, parent, false);
return new ViewHolderTwo(view, onExerciseClickListener);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
if (getItemViewType(position) == 0) {
ViewHolderOne viewHolderOne = (ViewHolderOne) holder;
if (adapterPos == position) {
viewHolderOne.relativeLayout.setBackgroundColor(Color.parseColor("#567845"));
}
else {
viewHolderOne.relativeLayout.setBackgroundResource(R.color.dark_grey);
}
viewHolderOne.textViewExerciseName.setText(String.valueOf(allCompletedExercises.get(position).getChildExerciseName()));
viewHolderOne.textViewSetNumber.setText(String.valueOf(viewHolderOne.getAdapterPosition() + 1));
viewHolderOne.textViewWeight.setText(String.valueOf(allCompletedExercises.get(position).getTotal_weight_lifted()));
viewHolderOne.textViewReps.setText(String.valueOf(allCompletedExercises.get(position).getReps()));
} else if (getItemViewType(position) == 1) {
ViewHolderTwo viewHolderTwo = (ViewHolderTwo) holder;
if (adapterPos == position) {
viewHolderTwo.relativeLayout.setBackgroundColor(Color.parseColor("#567845"));
} else {
viewHolderTwo.relativeLayout.setBackgroundResource(R.color.dark_grey);
}
viewHolderTwo.textViewSetNumber.setText(String.valueOf(viewHolderTwo.getAdapterPosition() + 1));
viewHolderTwo.textViewWeight.setText(String.valueOf(allCompletedExercises.get(position).getTotal_weight_lifted()));
viewHolderTwo.textViewReps.setText(String.valueOf(allCompletedExercises.get(position).getReps()));
}
}
#Override
public int getItemCount() {
return allCompletedExercises.size();
}
#Override
public int getItemViewType(int position) {
// if list is sorted chronologically
if (position == 0) {
return 0;
}
if (allCompletedExercises.get(position).getChildExerciseName().equals(allCompletedExercises.get(position - 1).getChildExerciseName())) {
return 1;
} else {
return 0;
}
}
public class ViewHolderOne extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView textViewExerciseName;
private TextView textViewSetNumber;
private TextView textViewWeight;
private TextView textViewReps;
OnExerciseClickListener mOnExerciseClickListener;
private RelativeLayout relativeLayout;
public ViewHolderOne(#NonNull View itemView, OnExerciseClickListener onExerciseClickListener) {
super(itemView);
textViewExerciseName = itemView.findViewById(R.id.textView_ExerciseName3);
textViewSetNumber = itemView.findViewById(R.id.textView_Set_Number56);
textViewWeight = itemView.findViewById(R.id.textView_weight78);
textViewReps = itemView.findViewById(R.id.textView_repss0);
mOnExerciseClickListener = onExerciseClickListener;
relativeLayout = (RelativeLayout) itemView.findViewById(R.id.exercise_item_relative);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
onExerciseClickListener.onExerciseClicked(getAdapterPosition());
if (isSelected) {
adapterPos = -1;
isSelected = false;
} else {
adapterPos = getAdapterPosition();
isSelected = true;
}
notifyDataSetChanged();
}
}
class ViewHolderTwo extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView textViewSetNumber;
private TextView textViewWeight;
private TextView textViewReps;
OnExerciseClickListener mOnExerciseClickListener;
private RelativeLayout relativeLayout;
public ViewHolderTwo(#NonNull View itemView, OnExerciseClickListener onExerciseClickListener) {
super(itemView);
textViewSetNumber = itemView.findViewById(R.id.textView_Set_Number);
textViewWeight = itemView.findViewById(R.id.textView_weight);
textViewReps = itemView.findViewById(R.id.textView_repss);
relativeLayout = (RelativeLayout) itemView.findViewById(R.id.exercise_item_rel);
mOnExerciseClickListener = onExerciseClickListener;
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
onExerciseClickListener.onExerciseClicked(getAdapterPosition());
if (!isSelected) {
adapterPos = getAdapterPosition();
isSelected = true;
} else {
adapterPos = -1;
isSelected = false;
}
notifyDataSetChanged();
}
}
public interface OnExerciseClickListener {
void onExerciseClicked(int position);
}
public double getWeight(int position) {
double weight = allCompletedExercises.get(position).getTotal_weight_lifted();
return weight;
}
public int getReps(int position) {
int reps = allCompletedExercises.get(position).getReps();
return reps;
}
}
In onSwipe(), just reset the adapterPos of your adapter object to -1 and call notifyItemChanged() on that position.
// backup the currently selected position
int selectedPos = adapter.adapterPos;
// change the currently selected position to -1
adapter.adapterPos = -1;
adapter.isSelected = false;
adapter.notifyItemChanged(selectedPos);
Note: onSwipe() is called after the ViewHolder being swiped fully.
I think the only thing you need to do for this to work is to make sure that notifyDataSetChanged() is executed once after you set adapterpos= -1.
notifyDataSetChanged() will reexecute onBindViewHolder for the entire adapter as opposed to notifyItemChanged() which should result in all items evaluating to a gray background.
you are actually already doing this in your viewholders onClick method in order to prevent multiple items to have a green background at once. so yust execute the method again after a swipe. so just do the following:
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
int logID = allExercises.get(viewHolder.getAdapterPosition()).getLog_id();
logViewModel.deleteByID(logID);
clearBtn.setVisibility(View.VISIBLE);
saveBtn.setText("Save");//<-- why if no item is selected?
// backup the currently selected position
//int selectedPos = adapter.adapterPos;<-- why would you do this, nothing is not shown as selected
// change the currently selected position to -1
adapter.adapterPos = -1;
adapter.notifyDataSetChanged();//now everything will be gray
}
this will work for sure but it will mess with the delete animation you might be using after the swipe. following the previous answer another code that might work is the following:
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
int copyOfAdapterPos=adapterPos;
adapterPos=-1;
notifyItemChanged(copyOfAdapterPos);
int logID = allExercises.get(viewHolder.getAdapterPosition()).getLog_id();
logViewModel.deleteByID(logID);
clearBtn.setVisibility(View.VISIBLE);
saveBtn.setText("Save");//<-- why if no item is selected?
adapter.notifyItemRemoved(viewHolder.getAdapterPosition());//now everything will be gray
}
i havnt tested it but if it works it will look nicer
I have a horizontal RecyclerView that displays 7 images from the users device (changing as user keeps taking pictures). I would like to add a default icon at the end of the 7 images, with an onclick capability. How can I go about doing this?
Something like this:
In the image above the plus icon should be the default icon, however it should be at the end of the images.
UPDATED:
RecentPhotosAdapter.java
public class RecentPhotosAdapter extends RecyclerView.Adapter<RecentPhotosAdapter.ViewHolder> {
// Variables
private Context mContext;
private ArrayList<String> mImage;
private int VIEW_TYPE_DEFAULT = 0;
private int VIEW_TYPE_IMAGE = 1;
// Limit the recent photo selection
int RECENT_PHOTO_LIMIT = 7;
public RecentPhotosAdapter(Context mContext, ArrayList<String> mImage) {
this.mContext = mContext;
this.mImage = mImage;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_IMAGE) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recent_photos_item, parent, false);
return new ViewHolder(view);
}
else {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.default_select_photos_item, parent, false);
return new ViewHolder(view);
}
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
if(position < Math.min(mImage.size(), RECENT_PHOTO_LIMIT)){
String images = mImage.get(position);
// Recent Photos
Glide.with(mContext)
.load(images)
.placeholder(R.drawable.background_gallery_placeholder)
.transform(new CenterCrop(), new RoundedCorners(30))
.into(holder.recent_photos_iv);
// Default select photos
holder.recent_photos_iv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Do something here
// Take user to image select slider
}
});
}
else {
//code for default view
}
}
#Override
public int getItemViewType(int position) {
return (position == mImage.size()) ? VIEW_TYPE_DEFAULT : VIEW_TYPE_IMAGE;
}
#Override
public int getItemCount() {
return Math.min(mImage.size(), RECENT_PHOTO_LIMIT) + 1;
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView recent_photos_iv;
ImageView default_select_photo_iv;
public ViewHolder(View itemView) {
super(itemView);
recent_photos_iv = itemView.findViewById(R.id.recent_photos_iv);
default_select_photo_iv = itemView.findViewById(R.id.default_select_photo_iv);
}
}
}
You can achieve this by making the default icon as a "ViewType" of your adapter.
Override getItemViewType to return a different value for your last item.
#Override
public int getItemViewType(int position) {
return (position == mData.size()) ? VIEW_TYPE_DEFAULT : VIEW_TYPE_IMAGE;
}
Now in the onCreateViewHolder, handle both the view Types.
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_IMAGE) {
//Create viewholder for your images
}
else {
//Create viewholder for default view
}
}
Add 1 to your ItemList size to accomodate this extra view:
#Override
public int getItemCount() {
return mData.size() + 1;
}
Your Updated code:
public class RecentPhotosAdapter extends RecyclerView.Adapter<RecentPhotosAdapter.ViewHolder> {
// Variables
private Context mContext;
private ArrayList<String> mImage;
private int VIEW_TYPE_DEFAULT=0;
private int VIEW_TYPE_IMAGE=1;
public RecentPhotosAdapter(Context mContext, ArrayList<String> mImage) {
this.mContext = mContext;
this.mImage = mImage;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_IMAGE) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recent_photos_item, parent, false);
return new ViewHolder(view);
}
else {
//Create viewholder for default view
}
}
#Override
public int getItemViewType(int position) {
return (position == Math.min(mImage.size(), RECENT_PHOTO_LIMIT)) ?VIEW_TYPE_DEFAULT : VIEW_TYPE_IMAGE;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
if(position < Math.min(mImage.size(), RECENT_PHOTO_LIMIT)){
String images = mImage.get(position);
Glide.with(mContext)
.load(images)
.placeholder(R.drawable.background_gallery_placeholder)
.transform(new CenterCrop(), new RoundedCorners(30))
.into(holder.recent_photos_iv);
holder.recent_photos_iv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Do something here
// Take user to image select slider
}
});
}
else {
//code for default view
}
}
#Override
public int getItemCount() {
// Limit the recent photo selection
int RECENT_PHOTO_LIMIT = 7;
return Math.min(mImage.size(), RECENT_PHOTO_LIMIT)+1;
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView recent_photos_iv;
public ViewHolder(View itemView) {
super(itemView);
recent_photos_iv = itemView.findViewById(R.id.recent_photos_iv);
}
}
}
I have a little bit problem.In my activity there is two Adapter one is for color selection and another is for size selection. While i clicked one of the item of color then recently the available size adapter should be change but i got problem in size adapter. it changes only when i click the size item. I research and try to solve problem but it doesnt works for me.
Here is my code.
AddToCartActivity.java
public class AddToCartActivity extends BaseActivity{
#Override
protected int getLayout() {
return R.layout.activity_add_to_cart;
}
#Override
protected void init() {
//api called here
}
// response of api
#Override
public void productDetail(ProductCommonModel productCommonModel,
ArrayList<ProductChildModel> productChildModels, HashMap<Integer,
ArrayList<ChildAttributeModel>> childWithAttribute, HashMap<Integer,
ArrayList<ChildImageModel>> childWithImages,
ArrayList<com.hazesoft.dokan.singleproductdetail.model.ColorModel>
colorModels, ArrayList<SizeModel> sizeModels,
ArrayList<RelatedProductModel> relatedProductModels) {
this.productCommonModel = productCommonModel;
this.productChildModels = productChildModels;
this.childWithAttribute = childWithAttribute;
this.childWithImages = childWithImages;
this.colorModels = colorModels;
this.sizeModels = sizeModels;
this.relatedProductModels = relatedProductModels;
tvProductName.setText(productCommonModel.getName());
if (productCommonModel.getSpecialPrice() == 0) {
tvSellingPrice.setText(getString(R.string.rs) + productCommonModel.getSellingPrice());
tvDiscount.setVisibility(View.GONE);
tvSpecialPrice.setVisibility(View.GONE);
} else {
tvSpecialPrice.setText(getString(R.string.rs) + productCommonModel.getSpecialPrice());
tvSellingPrice.setText(getString(R.string.rs) + productCommonModel.getSellingPrice());
tvSellingPrice.setPaintFlags(tvSellingPrice.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
tvDiscount.setText(productCommonModel.getDiscount() + getString(R.string.percentage));
}
setChildDetail(childWithAttribute, productChildModels);
setColorModel(colorModels);
setSizeModel(sizeModels);
quantity = Integer.parseInt(tvQuantityCart.getText().toString());
}
// setcolor adapter
private void setColorModel(ArrayList<ColorModel> colorModels) {
MyColorGridViewAdapter adapter = new MyColorGridViewAdapter(this, colorModels);
gvColor.setAdapter(adapter);
gvColor.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
adapter.setSelectedPostion(position);
adapter.notifyDataSetChanged();
}
});
}
// set size adapter
private void setSizeModel(ArrayList<SizeModel> sizeModels) {
sizeCustomModels = new ArrayList<>();
for(int i=0;i<sizeModels.size();i++){
sizeCustomModels.add(new SizeCustomModel(sizeModels.get(i).getAttName(),0));
}
setCustomSizeModelToAdapter(sizeCustomModels);
}
// this is code when i click color and change the size adapter but size doesnt change recently only changes when i click any item of the size
public void getSelectedC0lor(String color) {
selectedColor = color;
selectedSize=null;
sizeCustomModels = new ArrayList<>();
availableSize = new ArrayList<>();
for (int i = 0; i < skuColorSIzeList.size(); i++) {
if (skuColorSIzeList.get(i).getColor().equals(selectedColor)) {
availableSize.add(skuColorSIzeList.get(i).getSize());
}
}
for(int i=0;i<sizeModels.size();i++){
String size = null;
int status=0;
for(int j=0;j<availableSize.size();j++){
if(sizeModels.get(i).getAttName().equals(availableSize.get(j))){
size = sizeModels.get(i).getAttName();
status = 1;
break;
}else {
size = sizeModels.get(i).getAttName();
status = 0;
}
}
sizeCustomModels.add(new SizeCustomModel(size,status));
}
sizeRecylerAdapter.getNewModel(sizeCustomModels);
/*sizeRecylerAdapter = new MyCustomSizeRecylerAdapter(sizeCustomModels,this);
rvSize.setAdapter(sizeRecylerAdapter);
sizeRecylerAdapter.notifyDataSetChanged();*/
/*setCustomSizeModelToAdapter(sizeCustomModels);*/
}
}
MyColorGridViewAdapter.java
public class MyColorGridViewAdapter extends BaseAdapter {
Context context;
List<ColorModel> colorModelList;
String select_color;
boolean ch =false;
int checkPosition = -1;
public MyColorGridViewAdapter(Context context, List<ColorModel> colorModelList) {
this.context = context;
this.colorModelList = colorModelList;
}
public void setSelectedPostion(int postion){
this.checkPosition = postion;
}
#Override
public int getCount() {
return colorModelList.size();
}
#Override
public Object getItem(int position) {
return colorModelList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView==null){
convertView = LayoutInflater.from(context).inflate(R.layout.custom_color_list_item,null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
Picasso.with(context).load(colorModelList.get(position).getImage()).into(holder.ivImage);
holder.tvColorName.setText(colorModelList.get(position).getAttName());
if(checkPosition==position){
holder.ivChecked.setVisibility(View.VISIBLE);
select_color = colorModelList.get(position).getAttName();
if( context instanceof AddToCartActivity){
((AddToCartActivity) context).getSelectedC0lor(select_color);
}
}else {
holder.ivChecked.setVisibility(View.GONE);
}
if(colorModelList.size()==1){
holder.ivChecked.setVisibility(View.VISIBLE);
select_color = colorModelList.get(position).getAttName();
if( context instanceof AddToCartActivity){
((AddToCartActivity) context).getSelectedC0lor(select_color);
}
}
return convertView;
}
class ViewHolder{
#BindView(R.id.view)
LinearLayout view;
#BindView(R.id.tv_color_name)
TextViewHelper tvColorName;
#BindView(R.id.iv_image)
ImageView ivImage;
#BindView(R.id.iv_checked)
ImageView ivChecked;
public ViewHolder(View view) {
ButterKnife.bind(this,view);
}
}
}
MyCustomSizeRecylerAdapter.java
public class MyCustomSizeRecylerAdapter extends RecyclerView.Adapter<MyCustomSizeRecylerAdapter.MyViewHolder> {
ArrayList<SizeCustomModel> sizeModels;
Context context;
int checkPosition = -1;
String selectedSize;
public MyCustomSizeRecylerAdapter(ArrayList<SizeCustomModel> sizeModels, Context context) {
this.sizeModels = sizeModels;
this.context = context;
}
public void getNewModel(ArrayList<SizeCustomModel> customModels) {
sizeModels.clear();
this.sizeModels = customModels;
selectedSize = null;
Log.d("sizemodel", "getNewModel: " + new Gson().toJson(sizeModels));
notifyDataSetChanged();
}
public void getSelectedPosition(int position) {
checkPosition = position;
notifyDataSetChanged();
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.size_adapter, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.tv_sizeName.setText(sizeModels.get(position).getSize());
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_register);
if (sizeModels.get(position).getStock_Status() == 0) {
holder.ll_mainview.setClickable(false);
holder.ll_sizeAdapter.setBackgroundResource(R.color.blue_700);
} else if (sizeModels.get(position).getStock_Status() == 1) {
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_register);
if (checkPosition == position) {
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_green);
holder.tv_sizeName.setTextColor(context.getResources().getColor(R.color.white));
selectedSize = sizeModels.get(position).getSize();
if (context instanceof AddToCartActivity) {
((AddToCartActivity) context).getSelectSize(selectedSize);
}
} else {
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_register);
holder.tv_sizeName.setTextColor(context.getResources().getColor(R.color.tv_black));
}
if (sizeModels.size() == 1) {
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_green);
holder.tv_sizeName.setTextColor(context.getResources().getColor(R.color.white));
selectedSize = sizeModels.get(position).getSize();
if (context instanceof AddToCartActivity) {
((AddToCartActivity) context).getSelectSize(selectedSize);
}
}
}
}
#Override
public int getItemCount() {
return sizeModels.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
#BindView(R.id.tv_sizeName)
TextView tv_sizeName;
#BindView(R.id.ll_sizeAdapter)
LinearLayout ll_sizeAdapter;
#BindView(R.id.main_view)
LinearLayout ll_mainview;
public MyViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
At first both adapter will set data and after click color item the size adapter must be change but it only changes when i click any of the item. adapter.notifyDataSetChanged() doesnt work here for me.
Both Adapter set
When i click color item but doesnt change size adapter
when i click size item only change size adapter
Use Interface to bridge with two adapter and communicate with each other.
When scroll recyclerview some items mixes. After I add ads after every 15 items, holder get wrong data. Some items are vip items. I will change background color of these items. But when I scroll it dublicates mixes. How can I solve?
This is my adapter
private Context mCtx;
private List<Car> carList;
private RecyclerViewAnimator mAnimator;
private int AD_TYPE=1;
private int CONTENT_TYPE=2;
private int LIST_AD_DELTA=15;
public ProductAllCarAdapter(RecyclerView recyclerView,Context mCtx, List<Car> carList) {
this.mCtx = mCtx;
this.carList = carList;
mAnimator = new RecyclerViewAnimator(recyclerView);
}
#Override
public ProductAllCarAdapter.ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == AD_TYPE){
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_add_item, null);
ProductAllCarAdapter.ProductViewHolder vh = new ProductAllCarAdapter.ProductViewHolder(itemView);
mAnimator.onCreateViewHolder(itemView);
return vh;
} else {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_car_item, null);
ProductAllCarAdapter.ProductViewHolder vh = new ProductAllCarAdapter.ProductViewHolder(itemView);
mAnimator.onCreateViewHolder(itemView);
return vh;
}
}
#Override
public int getItemViewType(int position) {
if (position>0 && position % LIST_AD_DELTA == 0)
return AD_TYPE;
return CONTENT_TYPE;
}
#Override
public void onBindViewHolder(ProductAllCarAdapter.ProductViewHolder holder, int position) {
if (getItemViewType(position) == CONTENT_TYPE) {
final Car car = carList.get(holder.getAdapterPosition());
GlideApp.with(mCtx).load(car.getImg()).into(holder.imageView);
if (car.getVip() == 1) {
holder.relativeLayout.setBackgroundColor(ContextCompat.getColor(mCtx, R.color.colorVip));
holder.imageViewVIP.setVisibility(View.VISIBLE);
}
final String carid = String.valueOf(car.getCarid());
mAnimator.onBindViewHolder(holder.itemView, position);
} else {
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Context mcontext = view.getContext();
Bundle bundle = ActivityOptionsCompat.makeCustomAnimation(mcontext, android.R.anim.fade_in, android.R.anim.fade_out).toBundle();
Intent intent = new Intent(mcontext, AdsItem.class);
mcontext.startActivity(intent, bundle);
}
});
mAnimator.onBindViewHolder(holder.itemView, position);
}
}
private int getRealPosition(int position) {
if (LIST_AD_DELTA == 0) {
return position;
} else {
return position - position / LIST_AD_DELTA;
}
}
#Override
public long getItemId(int position) { return position; }
#Override
public int getItemCount() {
int additionalContent = 0;
if (carList.size() > 0 && carList.size() > LIST_AD_DELTA) {
additionalContent = ( carList.size() / LIST_AD_DELTA);
}
return carList.size() + additionalContent;
}
public static class ProductViewHolder extends RecyclerView.ViewHolder {
private View mView;
ImageView imageView, imageViewVIP;
RelativeLayout relativeLayout;
public ProductViewHolder(View itemView) {
super(itemView);
mView = itemView;
imageView = itemView.findViewById(R.id.imageView);
imageViewVIP = itemView.findViewById(R.id.imageViewVIP);
relativeLayout = itemView.findViewById(R.id.relativeLayoutpc);
}
public void setOnClickListener(View.OnClickListener listener) {
mView.setOnClickListener(listener);
}
}
I think problem onBindViewHolder function use wrong holder. ArrayList also return true value but on scroll it mixes.
You just have to add the corresponding else of the following if statement block.
if (car.getVip() == 1) {
holder.relativeLayout.setBackgroundColor(ContextCompat.getColor(mCtx, R.color.colorVip));
holder.imageViewVIP.setVisibility(View.VISIBLE);
} else {
holder.relativeLayout.setBackgroundColor(ContextCompat.getColor(mCtx, R.color.colorNormal));
holder.imageViewVIP.setVisibility(View.GONE);
}
This is inside your onBindViewHolder function where the view type is CONTENT_TYPE.
Hope that solves your problem.
I use StaggeredGridLayout in my Recycler View
What I need :
I can divide recycler view to 2 columns, but I don't know how to put main cell on top of the recycler view
I am not sure, but maybe I can put it in container and try to hide it during scrolling? Like we do with toolbar when user start to scroll toolbar gone up.
But I am not sure about it
How to put main cell on the top of StaggeredGridLayout(recycler view) ?
Thanks in advance!
Add these lines in onBindViewHolder method
if(position == 0){
StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
layoutParams.setFullSpan(true);
}
Eventually there is my adapter maybe will help someone to understand how does it work
public class AdapterRecViewMain
extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<BaseMarkerElement> mainCardList;
private final int HEADER_VIEW = 0;
private final int FOOTER_VIEW = 1;
public AdapterRecViewMain() {
}
public void setData(List<BaseMarkerElement> mainCardList) {
this.mainCardList = mainCardList;
}
#Override public int getItemViewType(int position) {
if (position == 0) {
return HEADER_VIEW;
}
return FOOTER_VIEW;
}
#Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
if (type == FOOTER_VIEW) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.card_main_activity, viewGroup, false);
return new MainCardViewHolder(v);
} else {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.header_view_main_activity, viewGroup, false);
return new HeaderViewHolder(v);
}
}
#Override public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int positionItem) {
final int position = viewHolder.getAdapterPosition();
if (viewHolder instanceof HeaderViewHolder) {
StaggeredGridLayoutManager.LayoutParams layoutParams =
(StaggeredGridLayoutManager.LayoutParams) viewHolder.itemView.getLayoutParams();
layoutParams.setFullSpan(true);
BaseMarkerElement item = mainCardList.get(position);
if (item instanceof HeaderView) {
HeaderView header = (HeaderView) mainCardList.get(position);
// need to add implementation
}
} else if (viewHolder instanceof MainCardViewHolder) {
MainCardViewHolder currentView = (MainCardViewHolder) viewHolder;
CardMainActivity currentCard = (CardMainActivity) mainCardList.get(position);
currentView.ivMainCard.setImageResource(currentCard.getIvMainCard());
currentView.tvBrandName.setText(currentCard.getTvBrandName());
currentView.tvPrice.setText(currentCard.getTvPrice());
currentView.tvType.setText(currentCard.getTvType());
}
}
#Override public int getItemCount() {
return mainCardList.size();
}
private class MainCardViewHolder extends RecyclerView.ViewHolder {
ImageView ivMainCard;
TextView tvBrandName;
TextView tvType;
TextView tvPrice;
MainCardViewHolder(View view) {
super(view);
ivMainCard = (ImageView) view.findViewById(R.id.imageViewMainCard);
tvBrandName = (TextView) view.findViewById(R.id.tvBrandName);
tvType = (TextView) view.findViewById(R.id.tvType);
tvPrice = (TextView) view.findViewById(R.id.tvPrice);
}
}
private class HeaderViewHolder extends RecyclerView.ViewHolder {
public HeaderViewHolder(View itemView) {
super(itemView);
}
}
}