i am doing simple cart application. which will show cart details in recycler view.
Here i am going to decrease the quantity value upto 1.The item going to be remove from item adapter.it will be working fine.But when i was going to decrease the second item quantity value,it will remove without checking the condition. My condition is if the quantity is below 1 the item going to remove.
ItemAdapter.java
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> {
Context context;
ArrayList<ItemData> itemDataList;
int quantity,t_amount;
totalAmount totalAmount;
public ItemAdapter(Context context, ArrayList<ItemData> itemDataList) {
this.context = context;
this.itemDataList = itemDataList;
totalAmount = (ItemAdapter.totalAmount) context;
}
#NonNull
#Override
public ItemAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_details,parent,false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int pos) {
ItemData itemData = itemDataList.get(pos);
holder.txtPrice.setText(itemData.getPrice());
holder.txtDesc.setText(itemData.getDescription());
holder.txtCartCount.setText(itemData.getCartCount());
holder.btnCartDec.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(quantity <= 1){
itemDataList.remove(holder.getAdapterPosition());
notifyItemRemoved(holder.getAdapterPosition());
notifyItemRangeChanged(holder.getAdapterPosition(),itemDataList.size());
}else {
quantity = Integer.parseInt(itemDataList.get(pos).getCartCount());
quantity = quantity-1;
itemDataList.get(pos).setCartCount(String.valueOf(quantity));
notifyDataSetChanged();
holder.txtCartCount.setText(String.valueOf(quantity));
}
}
});
holder.btnCartInc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
quantity = Integer.parseInt(itemDataList.get(pos).getCartCount());
quantity = quantity+1;
itemDataList.get(pos).setCartCount(String.valueOf(quantity));
notifyDataSetChanged();
holder.txtCartCount.setText(String.valueOf(quantity));
}
});
}
#Override
public int getItemCount() {
return itemDataList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView txtPrice, txtDesc, txtCartCount, btnCartDec, btnCartInc;
public ViewHolder(#NonNull View itemView) {
super(itemView);
txtPrice = itemView.findViewById(R.id.itemView_price);
txtDesc = itemView.findViewById(R.id.itemView_desc);
txtCartCount = itemView.findViewById(R.id.itemView_Count);
btnCartDec = itemView.findViewById(R.id.itemViewDec);
btnCartInc = itemView.findViewById(R.id.itemViewInc);
}
}
public interface totalAmount{
void t_amount(int amount);
}
}
Just need knows the item position and adds below code in adapter
mDataset.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mDataSet.size());
You must get the quantity related to the position before your if condition. In your case the quantity value is the previous value, that's why the if condition is true.
holder.btnCartDec.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// You must get the quantity of the currently clicked item here
quantity = Integer.parseInt(itemDataList.get(pos).getCartCount());
if(quantity <= 1){
itemDataList.remove(holder.getAdapterPosition());
notifyItemRemoved(holder.getAdapterPosition());
notifyItemRangeChanged(holder.getAdapterPosition(),itemDataList.size());
}else {
quantity = Integer.parseInt(itemDataList.get(pos).getCartCount());
quantity = quantity-1;
itemDataList.get(pos).setCartCount(String.valueOf(quantity));
notifyDataSetChanged();
holder.txtCartCount.setText(String.valueOf(quantity));
}
}
});
you can remove your item from model at specific position.After that notify Adapter that some changes has been done in list using notifyDataSetChanged();.
list.remove(getAdapterPosition())
notifyDataSetChanged();
You can remove from list of that position and notify adater ,it will remove.
replace this code
itemDataList.remove(holder.getAdapterPosition());
notifyItemRemoved(holder.getAdapterPosition());
notifyItemRangeChanged(holder.getAdapterPosition(),itemDataList.size());
to this
itemDataList.remove(holder.getAdapterPosition());notifyDataSetChanged();
it will work
Related
App Screen
I want to automatically get the sum of the items once added in the recycler view and at the same time get the sum of the items when the Quantity changes and when an item from the recyclerView is removed. I am new in Android, and I cannot think of any way to achieve this. I am thinking something like the code below, but I don't know how to implement it.
TextView ProductPrice = itemView.findViewById(R.id.productPricelbl);
TextView QTY = itemView.findViewById(R.id.Quantity);
Int total;
private void GetTotal(){
total += Integer.parseInt(ProductPrice.getText().toString()) * Integer.parseInt(QTY .getText().toString())
}
I am using a custom adapter for my recycler view with the code below
public class ListViewAdapter extends RecyclerView.Adapter<DemoVH>{
ArrayList<ProductListViewModel> productList;
Context mContext;
public ListViewAdapter(ArrayList<ProductListViewModel> productList, Context context) {
this.productList = productList;
this.mContext = context;
}
#NonNull
#Override
public DemoVH onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_view_row,parent,false);
return new DemoVH(view).linkadapter(this);
}
#Override
public void onBindViewHolder(#NonNull DemoVH holder, int position) {
final ProductListViewModel productListViewModel = productList.get(position);
holder.Product_Name.setText(productListViewModel.getProductName());
holder.Product_Barcode.setText(productListViewModel.getProductBarcode());
holder.Product_Price.setText(productListViewModel.getProductPrice());
}
#Override
public int getItemCount() {
return productList.size();
}
}
class DemoVH extends RecyclerView.ViewHolder{
TextView Product_Name;
TextView Product_Barcode;
TextView Product_Price;
TextView Product_QTY;
ImageView addQTY;
ImageView lessQTY;
private ListViewAdapter myAdapter;
int Quantity = 1;
public DemoVH(#NonNull View itemView) {
super(itemView);
Product_Name = itemView.findViewById(R.id.ProductNameLbl);
Product_Barcode = itemView.findViewById(R.id.ProductBarcodeLbl);
Product_Price = itemView.findViewById(R.id.ProductPriceLbl);
Product_QTY = itemView.findViewById(R.id.QTYLbl);
addQTY = itemView.findViewById(R.id.AddQTYBtn);
lessQTY = itemView.findViewById(R.id.lessQTYBtn);
itemView.findViewById(R.id.RemoveBtn).setOnClickListener(view -> {
myAdapter.productList.remove(getAdapterPosition());
myAdapter.notifyItemRemoved(getAdapterPosition());
});
addQTY.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Quantity = Quantity+=1;
Product_QTY.setText(String.valueOf(Quantity));
}
});
lessQTY.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(Quantity == 1){
Product_QTY.setText("1");
}else{
Quantity = Quantity-=1;
Product_QTY.setText(String.valueOf(Quantity));
}
}
});
}
public DemoVH linkadapter(ListViewAdapter adapter){
myAdapter = adapter;
return this;
}
}
You can take a global variable in recycler view adapter and keep adding the amount in that variable in onBindViewHolder().
And when any item is increased or decreased or removed you can add or decrease that amount from that global variable.
I'm facing the next problem.
I have a RecyclerView with the Adapter, the items, etc.
What I need is: Select an item in the recycler, change the color of that item, and then I have to disable the rest of the other items. It's like a RadioButton list.
I select one and disable the others. If I select again the same item, enable all the list.
I already have the onClick Button listener. I need to know if I have to reload again de list, If I have to loop and disable item by item, etc.
Thanks
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<Human> humans;
private HumanClick selectedHuman;
#Inject
public MyAdapter() {
}
public void init(List<Human> humanList, SelectedHumanClick humanClick){
this.humans = humanList;
this.humanClick = humanClick;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_Human, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final MyViewHolder holder, int position) {
final Human human = Humans.get(position);
holder.bind(Humans.get(position));
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectedHumanClick.onSelectedHumanClick(Human);
}
});
}
#Override
public int getItemCount() {
return humans != null ? Humans.size() : 0;
}
public final class MyViewHolder extends RecyclerView.ViewHolder {
#BindView(R.id.text_view_human_name)
TextView textView;
#BindView(R.id.image_view_profile)
ImageView imageViewProf;
#BindView(R.id.image_view_radio_btn)
ImageView imageViewRB;
private boolean isChecked = false;
public MyViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
public void bind(final Human Human) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
humanClick.onSelectedHumanClick(Human);
}
});
textView.setText(human.getName());
}
public void changeRBImage() {
if(!isChecked){
isChecked = true;
imageViewRB.setBackground(ContextCompat.getDrawable(imageViewRB.getContext(), R.drawable.selected));
}
else{
isChecked = false;
imageViewRB.setBackground(ContextCompat.getDrawable(imageViewRB.getContext(), R.drawable.not_selected));
}
}
}
My Recycler is defined inside a fragment here:
public class HumansFragment implenets HumanClick{
#BindView(R.id.recycler_humans)
RecyclerView humansRecyclerView;
#Inject
MyAdapter myAdapter;
.
.
.
public void loadHumans(List<Human> humans) {
myAdapter.init(Humans, this);
humansRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
humansRecyclerView.setAdapter(myAdapter);
}
#Override
public void humansClick(Human human) {
//TODO
}
}
I'm thinking in something like this, using setOnItemClickListener and check the position of the item clicked. The position is the index of the item clicked check the last event and new, if both are equal change color, if not dont do anything like disabling.
private ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
textView = (TextView)view.findViewById(android.R.id.text1);
}
#Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "position = " + getLayoutPosition(), Toast.LENGTH_SHORT).show();
//go through each item if you have few items within recycler view
if(getLayoutPosition()==0){
//Do whatever you want here
}else if(getLayoutPosition()==1){
//Do whatever you want here
}else if(getLayoutPosition()==2){
}else if(getLayoutPosition()==3){
}else if(getLayoutPosition()==4){
}else if(getLayoutPosition()==5){
}
//or you can use For loop if you have long list of items. Use its length or size of the list as
for(int i = 0; i<exampleList.size(); i++){
}
}
}
Or something smaller
RecyclerView recyclerView = findViewById(R.id.recycler);
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(context, recyclerView ,new
RecyclerItemClickListener.OnItemClickListener() {
#Override public void onItemClick(View view, int position) {
// do whatever
}
#Override public void onLongItemClick(View view, int position) {
// do whatever
}
})
);
I've implemented a recyclerview with staggered gridLayout containing about 31 items in the arrayList, recyclerview is working correctly, but I faced issue relating to single item selection.
When I select the value till "26" as shown in figure, its working fine
But, when I select the value after "26", the values from top most item are also selected, as shown in this next figure.
I require to only select one item at a time.
I've implemented the following code in my adapter class
public class DialogAdapter extends
RecyclerView.Adapter<DialogAdapter.DialogHolder>
{
// components
public Context context;
public ArrayList<AlertDialogModel> dialogArrayList = new
ArrayList<AlertDialogModel>();
private final ArrayList<Integer> selected = new ArrayList<>();
private int lastCheckedPosition = -1;
public Interface interface;
// parameterized constructor
public DialogAdapter(Context context, ArrayList<AlertDialogModel>
dialogArrayList,Interface interface)
{
this.context = context;
this.dialogArrayList = dialogArrayList;
this.interface = interface;
}
#NonNull
#Override
public DialogHolder onCreateViewHolder(#NonNull ViewGroup parent, int
viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_cardview,parent,false);
DialogHolder dialogHolder = new DialogHolder(view);
return dialogHolder;
}
#Override
public void onBindViewHolder(#NonNull final DialogHolder holder, final int position)
{
final AlertDialogModel alertDialogModel = dialogArrayList.get(position);
holder.textView.setText(alertDialogModel.getDisplayValue());
if(lastCheckedPosition == position)
{
holder.textView.setTextColor(context.getResources().getColor(R.color.white));
holder.textView.setBackground(context.getResources().getDrawable(R.drawable.circular_shape_selection));
}
else
{
}
holder.textView.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
lastCheckedPosition = position;
notifyDataSetChanged();
holder.textView.setTextColor(context.getResources().getColor(R.color.white));
holder.textView.setBackground(context.getResources().getDrawable(R.drawable.circular_shape_selection));
interface.getSelectedValue(alertDialogModel.getDisplayValue());
}
});
}
#Override
public int getItemCount()
{
return dialogArrayList.size();
}
public static class DialogHolder extends RecyclerView.ViewHolder
{
public TextView textView;
public DialogHolder(View itemView)
{
super(itemView);
textView = (TextView)itemView.findViewById(R.id.textView);
}
}
}
Can anyone relate my code and identify the issue ?
holder.textView.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
lastCheckedPosition = position;
notifyDataSetChanged();
holder.textView.setTextColor(context.getResources().getColor(R.color.white));
holder.textView.setBackground(context.getResources().getDrawable(R.drawable.circular_shape_selection));
interface.getSelectedValue(alertDialogModel.getDisplayValue());
//below line is important to remove previous selected position from the variable
lastCheckedPosition = -1;
}
});
you should put the text view to the original state:
if(lastCheckedPosition == position)
{
holder.textView.setTextColor(context.getResources().getColor(R.color.white));
holder.textView.setBackground(context.getResources().getDrawable(R.drawable.circular_shape_selection));
}
else
{
holder.textView.setTextColor(context.getResources().getColor(R.color.transparent));
holder.textView.setBackground(null));
}
The title seems confusing because I cannot explain this properly using text.
I'll try my best to explain my problem.
Currently I have items in my recyclerview :
Each item contains a delete button that will remove the item in the recyclerview.
Lets assume that I have 5 items in the list:
what I want to attain is when the user deletes
Item 2
the information/data from item 3 will be transferred to Item 2,
the data from item 4 will be transferred to item 3 and
the data from item 5 will be transferred to item 4
and lastly the item 5 will be deleted.
I currently have no code for this but I'm trying my best to construct it.
Here is my adapter code, it might help:
public class CreditCard_PostPayAdapter extends RecyclerView.Adapter<CreditCard_PostPayAdapter.MyViewHolder> {
private static String TAGedittext = "";
//private final AccountHistoryTransactionActivity homeActivity;
private Context mContext;
private ArrayList<Integer> mHeaderText;
CreditCard_PostPayAdapter adapter;
public CreditCard_PostPayAdapter(Context mContext, ArrayList<Integer> mHeaderTextList ) {
this.mContext = mContext;
this.mHeaderText = mHeaderTextList;
}
#Override
public CreditCard_PostPayAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.creditcard_postpay_item, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final CreditCard_PostPayAdapter.MyViewHolder holder, int position) {
final int pos = position + 1;
final int mPosition = position;
if (mHeaderText.size() == 1) {
holder.mDeleteButton.setVisibility(View.GONE);
} else {
holder.mDeleteButton.setVisibility(View.VISIBLE); }
holder.mDeleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mHeaderText.remove(mPosition);
ArrayList<Integer> temp = new ArrayList<Integer>();
for (int i = 0 ; mHeaderText.size() - 1 >= i ; i++) {
temp.add(i);
Log.d("Counter++",""+i);
}
holder.mMerchantName.setText("");
holder.mTransactionAmountEditText.setText("");
holder.mTransactionDateEditText.setText("");
holder.mPostingDateEditText.setText("");
mHeaderText.clear();
mHeaderText.addAll(temp);
notifyDataSetChanged();
}
});
}
#Override
public int getItemCount() {
return mHeaderText.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView mHeaderTitle
public ImageView mArrowHeader;
public ImageButton mDeleteButton;
public TextInputEditText mTransactionDateEditText,
mPostingDateEditText,
mTransactionAmountEditText;
public MyViewHolder(View view) {
super(view);
this.mHeaderTitle = (TextView) view.findViewById(R.id.header_title);
this.mDeleteButton = view.findViewById(R.id.mDeleteButton);
this.mMerchantName = view.findViewById(R.id.mMerchantNameTextView);
this.mTransactionDateEditText = view.findViewById(R.id.Transaction_date);
this.mPostingDateEditText = view.findViewById(R.id.posting_date);
this.mTransactionAmountEditText = view.findViewById(R.id.Transaction_amount);
}
}
}
My current delete button function is to:
Delete the item(n) and recount all of the remaining item.
Replace your onBindViewHolder method and try,
#Override
public void onBindViewHolder(final CreditCard_PostPayAdapter.MyViewHolder holder, int position) {
holder.mDeleteButton.setTag(position);
holder.mDeleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int clickedPos = (int) view.getTag();
mHeaderText.remove(clickedPos);
notifyItemRemoved(position);
}
});
}
If you want to delete the 2nd element. delete the element and remaining will be taken care by recyclerAdapter to remove the row and align the data.
inside your onClickListener, remove the data from ArrayList and the call notifyItemRemoved()
write your onClick inside ViewHolder class
onClick(View view){
mHeaderText.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());
}
i hope this will help you..
you an delete the item in list and refresh your adapter by just doing this in your onClick:
holder.mDeleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mHeaderText.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mHeaderText.size());
}
});
I am developing an android app in which I use a RecyclerView. Suppose I have 6 items in my RecyclerView i.e. [A, B, C, D, E, F]. So how can I get the number of clicks on these items?
For example:
If an user open item B 4 times. How can I get the count = 4?
P.s. count should increase only when the user click on the same item.
First declare static count variables for each items
private static int aCount = 0;
Then inside your onBindViewHolder, pass a method after the button click along with your position id.
public void onBindViewHolder(ItemAdapter.ViewHolder holder, int position) {
holder.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
thisWasClicked(position);
}
}
}
The method will be something like this
private void thisWasClicked(int position) {
if (position == 0) {
aCount++;
}
}
in holder
itemView.setOnClickListener(){
onClick(){
// count up
}
}
each item needs also an id to know, which item it is
I've made an example
CustomItem object
public class CustomItem {
private String item;
private int click;
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public int getClick() {
return click;
}
public void setClick(int click) {
this.click = click;
}
}
CustomAdapter and CustomViewHolder for the recyclerview
public class CustomAdapter extends RecyclerView.Adapter{
private List<CustomItem> itemList;
public CustomAdapter(List<CustomItem> itemList){
this.itemList = itemList;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new CustomViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.viewholder_generic, parent, false));;
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//increase click count for the current item
itemList.get(holder.getAdapterPosition()).setClick(itemList.get(holder.getAdapterPosition()).getClick() + 1);
}
});
}
#Override
public int getItemCount() {
return itemList.size();
}
// Custom ViewHolder
public class CustomViewHolder extends RecyclerView.ViewHolder {
//add fields you need
public CustomViewHolder(View itemView) {
super(itemView);
}
}
}
You can create a Map<Integer, Integer> clicksMap = new HashMap<>() in your adapter
You should also pass an interface to your ViewHolder that acts as a click Listener. Something like.
public interface OnItemLick {
void onItemClick(int position, int id);
}
Then declare an instance of this interface in your adapter.
OnItemLick listener = new OnItemClick() {
void onItemClick(int position, int id) {
//you can either use the item position or an id (if you have an unique one for the items). I will show an example using the position.
int count;
if(clicksMap.contains(position)) {
count = clickMap.get(position);
count ++;
clickMap.put(position, count);
}else {
count ++;
clickMap.put(position, count); }
}
In the end you clicksMap will contain the click count for every position of the items in the recycler.