I have an ArrayList<Model> type and having fields id,name,isSelected and I have one HashMap which can store only selected items means if the item is clicked it will be stored in HashMap<Intere,Model>, Integer will be id , Model is that object which can be selected. I want to update Arraylist item field isSeleted to true which is present in hashmap. How can i do? I have tried many condition but nothing is working fine.
ArrayList<MainInterestModel> mainInterestList;
public static HashMap<Integer, MainInterestModel> mainIntrestHash = new HashMap<>();
Iterator myVeryOwnIterator = mainIntrestHash.keySet().iterator();
while (myVeryOwnIterator.hasNext()) {
int key = (int) myVeryOwnIterator.next();
MainInterestModel value = (MainInterestModel) mainIntrestHash.get(key);
int id = value.getId();
for (int i = 0; i < mainInterestList.size(); i++) {
MainInterestModel model = mainInterestList.get(i);
if (model.getId() == id) {
model.setSelected(true);
mainInterestList.set(i, model);
} else {
model.setSelected(false);
mainInterestList.set(i, model);
}
}
}
By Default isSelected is false but when the user will click that item will be stored in HashMap later i want to update selection so user interface will show selected items. HashMap has selected items and arraylist have all items but isSelected are false. at the time of showing selected items, I'm taking isSelected is true or not, which working fine, but arraylist update is not working.
My adapter class code
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position) {
final MainInterestModel mainInterestModel = mainInterestModels.get(position);
holder.tvName.setText(mainInterestModel.getName());
holder.ivMainInterest.setImageResource(mainInterestModel.getImage());
// here isSelected is always false because in activity infalting adpter with arraylist, i want to setSeletced by hash object
boolean isSelected = mainInterestModel.isSelected();
if (isSelected) {
holder.ivMainInterest.setImageResource(R.drawable.bath_selector);
Log.e("Is Item selected ::", "" + mainInterestModel.getId());
} else {
holder.ivMainInterest.setImageResource(R.drawable.ic_bath);
Log.e("Is Item deselected ::", "" + mainInterestModel.getId());
}
holder.ivMainInterest.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
boolean selection = mainInterestModel.isSelected();
if (selection) {
holder.ivMainInterest.setImageResource(R.drawable.ic_bath);
mainInterestModel.setSelected(false);
mainIntrestHash.remove(mainInterestModel.getId());
Log.e("After Remove SIZE:---", "" + mainIntrestHash.size());
} else {
mainInterestModel.setSelected(true);
holder.ivMainInterest.setImageResource(R.drawable.bath_selector);
mainIntrestHash.put(mainInterestModel.getId(), mainInterestModel);
Log.e("After Adding SIZE:---", "" + mainIntrestHash.size());
}
}
});
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position) {
holder.ivMainInterest.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
boolean selection = mainInterestModel.isSelected();
if (selection) {
holder.ivMainInterest.setImageResource(R.drawable.ic_bath);
mainInterestModel.setSelected(false);
} else {
mainInterestModel.setSelected(true);
holder.ivMainInterest.setImageResource(R.drawable.bath_selector);
}
notifyDataSetChanged();
}
});
}
remove hashmap and try to use this.
use this
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
public class ModelIterator {
public static void main(String arg[]) {
ArrayList<mainModel> mainmoldelList = new ArrayList<mainModel>();
for (int i = 1; i <= 3; i++) {
mainModel m = new mainModel();
m.setId(i);
m.setName("Rajendra" + i);
m.setSelected(false);
mainmoldelList.add(m);
}
mainModel m = new mainModel();
m.setId(0);
m.setName("Rajendra0");
m.setSelected(false);
HashMap<Integer, mainModel> mMap = new HashMap<Integer, mainModel>();
mMap.put(1, m);
Iterator<Entry<Integer, mainModel>> ite = mMap.entrySet().iterator();
while (ite.hasNext()) {
Map.Entry<Integer, mainModel> pair = (Map.Entry<Integer, mainModel>) ite
.next();
int key = pair.getKey();
mainModel mObj = (mainModel) mMap.get(key);
for (int i = 0; i < mainmoldelList.size(); i++) {
if (mainmoldelList.get(i).id == key) {
mainModel tmp = new mainModel();
tmp.setId(mainmoldelList.get(i).id);
tmp.setName(mainmoldelList.get(i).name);
tmp.setSelected(true);
mainmoldelList.add(tmp);
mainmoldelList.remove(i);
}
}
}
for (int i = 0; i < mainmoldelList.size(); i++) {
System.out.println(mainmoldelList.get(i).id + " "
+ mainmoldelList.get(i).name + " "
+ mainmoldelList.get(i).isSelected);
}
}
}
Related
I have a "favourite" button for each row of my recyclerview which the user clicks when the like the image (obviously). Each row is a cardview that I only want to "flip" when the user opens the fragment.
When the user clicks the button I update my database with "Y" or "N".
My problem is that my recyclerview refreshes even though the list hasn't changed. When it refreshes all my cards flip which I do not want. How can I stop the recyclerview from updating when the button is clicked?
Here is my adapter class
#Override
public void onBindViewHolder(#NotNull final ClothesViewHolder holder, final int position) {
String image;
if (flip) {
holder.flipView.flipTheView();
}
ClothingItem current = mClothingItems.get(position);
holder.itemNameView.setText(current.getItem());
holder.categoryNameView.setText(current.getCategory());
holder.seasonNameView.setText(current.getSeason());
Integer yesCount = current.getYesCount();
Integer noCount = current.getNoCount();
if (current.getFavourite().equalsIgnoreCase("N")) {
holder.animationView.setProgress(0);
}
else {
holder.animationView.setProgress(1);
}
holder.yesTextView.setText(String.valueOf(yesCount));
holder.noTextView.setText(String.valueOf(noCount));
image = current.getPhotoPath();
Glide.with(holder.cardView)
.load(image)
.into(holder.pictureView);
flip = false;
} catch (NullPointerException e) {
Log.e("Picture","onBindViweHolder: Null Point:" + e.getMessage());
}
holder.animationView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onFavouriteClick(position);
}
});
public interface clickButtons {
void onFavouriteClick(int position);
}
Fragment Class
#Override
public void onFavouriteClick(int position) {
RecyclerView.ViewHolder holder = recyclerView.findViewHolderForAdapterPosition(position);
LottieAnimationView animationView = holder.itemView.findViewById(R.id.favouriteAnimation);
ClothingItem item = springList.get(position);
final Long id = item.getId();
if (animationView.getProgress() > 0) {
animationView.setProgress(0);
mClothingViewModel.updateFavourite(id.intValue(), "N");
adapter.notifyItemChanged(position,"favourite");
} else if (animationView.getProgress() == 0) {
animationView.playAnimation();
mClothingViewModel.updateFavourite(id.intValue(),"Y");
}
}
I tried to use onBindViewHolder with payloads but I get the same result. I think I'm not calling this properly
adapter.notifyItemChanged(position,"favourite");
Adapter class
#Override
public void onBindViewHolder(final ClothesViewHolder holder ,final int position, final List<Object> payloads){
String image;
if(!payloads.isEmpty()) {
ClothingItem current = mClothingItems.get(position);
holder.itemNameView.setText(current.getItem());
holder.categoryNameView.setText(current.getCategory());
holder.seasonNameView.setText(current.getSeason());
Integer yesCount = current.getYesCount();
Integer noCount = current.getNoCount();
if(yesCount == null) {
yesCount = 0;
}
if (noCount == null) {
noCount = 0;
}
if (current.getFavourite() == null || current.getFavourite().equalsIgnoreCase("N")) {
holder.animationView.setProgress(0);
}
else {
holder.animationView.setProgress(1);
}
// Log.d("Counting","Yes count " + yesCount + " no count " + noCount);
holder.yesTextView.setText(String.valueOf(yesCount));
holder.noTextView.setText(String.valueOf(noCount));
image = current.getPhotoPath();
Glide.with(holder.cardView)
.load(image)
.into(holder.pictureView);
} else {
onBindViewHolder(holder,position);
}
}
Fragment
#Override
public void onFavouriteClick(int position) {
RecyclerView.ViewHolder holder = recyclerView.findViewHolderForAdapterPosition(position);
LottieAnimationView animationView = holder.itemView.findViewById(R.id.favouriteAnimation);
ClothingItem item = springList.get(position);
final Long id = item.getId();
if (animationView.getProgress() > 0) {
animationView.setProgress(0);
mClothingViewModel.updateFavourite(id.intValue(), "N");
adapter.notifyItemChanged(position,"favourite");
} else if (animationView.getProgress() == 0) {
animationView.playAnimation();
mClothingViewModel.updateFavourite(id.intValue(),"Y");
adapter.notifyItemChanged(position,"favourite");
}
}
Recyclerview is updated or refreshed when notifiydataSetChanged is called.
try to remove notifiyDataSetChanged in the click event maybe
I've two class autoCompleteTextfiled.java and BillingController.java.
AutocompleteTextFilled is a custom class. When I select a popup I'm getting result.
code is below:
private void populatePopup(List<String> searchResult) {
List<CustomMenuItem> menuItems = new LinkedList<>();
// If you'd like more entries, modify this line.
int maxEntries = 10;
int count = Math.min(searchResult.size(), maxEntries);
for (int i = 0; i < count; i++)
{
final String result = searchResult.get(i);
Label entryLabel = new Label(result);
CustomMenuItem item = new CustomMenuItem(entryLabel, true);
item.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent actionEvent) {
setText(result);
selectedTextFromMenu(result);
entriesPopup.hide();
}
});
menuItems.add(item);
}
entriesPopup.getItems().clear();
entriesPopup.getItems().addAll(menuItems);
}
private void selectedTextFromMenu(String result) {
AutoCompleteTextField autoCompleteTextField = new AutoCompleteTextField();
ItemSelectedListener mListener = new BillingController();
autoCompleteTextField.registerOnGeekEventListener(mListener);
autoCompleteTextField.selectItemListener(result);
}
public interface ItemSelectedListener
{
void getSelectedResult(String result);
}
public void registerOnGeekEventListener(ItemSelectedListener mListener)
{
this.itemSelectedListener = mListener;
}
public void selectItemListener(String result)
{
if (this.itemSelectedListener != null) {
itemSelectedListener.getSelectedResult(result);
}
}
but i trying to access a result from BillingControllerClass to AutoCompleteTextFiled returns null.
#Override
public void getSelectedResult(String result) {
System.out.println("The pin has been changed>"+billingItemDetails.size());//billingItemDetails retunes 0
for (int j= 0; j<billingItemDetails.size();j++)
{
ItemListRequestAndResponseModel.item_list item_list = billingItemDetails.get(j);
if (item_list.getItem_name().equals(result))
{
System.out.println("The pin has been changed---->"+result);
txtFieldId.setText(item_list.getShort_code());//Textfiledis retunes null
}
}
}
}
But billingItemDetails(Arraylist) retuns 0. But initially ArrayList have a data.
Please Help me.
I am implementing an Adapter to take List and Hashmap and turn them into headers and children respectively for an Expandable ListView. In the constructor's Log statements it is showing that the values are being transferred to the local list successfully. But then it suddenly turns null.
I can't pinpoint what went wrong and where. Please help.
Here is my code for the Adapter class:
class ExpandableListViewAdapterDemo extends BaseExpandableListAdapter{
Context context = null;
private List<String> headersList;//semester's name and year
private HashMap<String, List<String>> tableList;//course names with its grades and gpa
static final String TAG = "**Adapter Demo**";
ExpandableListViewAdapterDemo(Context context, List<String> list,
HashMap<String, List<String>> hashMap){
this.context = context;
headersList = list;
tableList = hashMap;
Log.e(TAG, "hashmap list value = "+hashMap.get("Spring 2016"));
Log.e(TAG, "initial table list value = "+tableList.get("Spring 2016"));
printMap(tableList);
//printAll();
Log.e(TAG, "groupCount = "+getGroupCount());
}
void printAll(){
Log.e(TAG, "headers count = "+headersList.size());
for (int i = 0; i < headersList.size() ; i++) {
Log.e(TAG, "header at i="+i+" ,"+headersList.get(i));
}
printMap(tableList);
}
private static void printMap(HashMap mp) {
Iterator it = mp.entrySet().iterator();
while (it.hasNext()) {
HashMap.Entry pair = (HashMap.Entry)it.next();
Log.e(TAG, "#253 : "+pair.getKey() + " = " + pair.getValue());
it.remove(); // avoids a ConcurrentModificationException
}
}
#Override
public int getGroupCount() {
Log.e(TAG, "#299 : table list value = "+tableList.get("Spring 2016"));
return headersList.size();
}
#Override
public int getChildrenCount(int i) {
//Log.e(TAG, "at i="+i+" "+headersList.get(i));
int returns = 0;
Log.e(TAG, "#307 : table list value = "+tableList.get("Spring 2016"));
if (tableList.get(headersList.get(i)) != null)
returns = tableList.get(headersList.get(i)).size();
else
Log.e(TAG, "tableList is null");
Log.e(TAG, "details size = "+returns);
Log.e(TAG, "group count = "+getGroupCount());
int tosubtract = 2 * getGroupCount();
if (returns>tosubtract)
returns = returns - tosubtract - 2;
Log.e(TAG, "child count returns = "+String.valueOf(returns) );
return i;
}
#Override
public Object getGroup(int i) {
Log.e(TAG, "#323 : table list value = "+tableList.get("Spring 2016"));
return headersList.get(i);
}
#Override
public Object getChild(int i, int i1) {
Log.e(TAG, "#329 : table list value = "+tableList.get("Spring 2016"));
return tableList.get(headersList.get(i)).get(i1);
}
#Override
public long getGroupId(int i) {
Log.e(TAG, "#335 : table list value = "+tableList.get("Spring 2016"));
return i;
}
#Override
public long getChildId(int i, int i1) {
Log.e(TAG, "#340 : table list value = "+tableList.get("Spring 2016"));
return i1;
}
#Override
public boolean hasStableIds() {
Log.e(TAG, "#347 : table list value = "+tableList.get("Spring 2016"));
return false;
}
#Override
public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
Log.e(TAG, "#353 : table list value = "+tableList.get("Spring 2016"));
String semesterTitle = (String) getGroup(i);
if (view == null){
LayoutInflater inf = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inf.inflate(R.layout.previous_semesters_result_list_headers, null);
}
TextView semesterName = (TextView) view.findViewById(R.id.semester_name);
semesterName.setText(semesterTitle);
return view;
}
#Override
public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
Log.e(TAG, "#367 : table list value = "+tableList.get("Spring 2016"));
String courseIdTitle = (String) getChild(i, i1);
String gpa = (String) getChild(i, i1+getChildrenCount(i));//previously i1+4
String grade = (String) getChild(i, i1+getChildrenCount(i)+getChildrenCount(i));
if (view == null){
LayoutInflater inf = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inf.inflate(R.layout.previous_semesters_results_list_child, null);
}
TextView courseIdValue = (TextView) view.findViewById(R.id.course_id_column_value);
courseIdValue.setText(courseIdTitle);
TextView gradeValue = (TextView) view.findViewById(R.id.grade_column_value);
gradeValue.setText(grade);
TextView gpaValue = (TextView) view.findViewById(R.id.gpa_column_value);
gpaValue.setText(gpa);
return view;
}
#Override
public boolean isChildSelectable(int i, int i1) {
Log.e(TAG, "#386 : table list value = "+tableList.get("Spring 2016"));
return true;
}
}
Here is my Log :
You removed the item while printing the map,
it.remove(); // avoids a ConcurrentModificationException
Just remove this it will work fine.
private static void printMap(HashMap mp) {
Iterator it = mp.entrySet().iterator();
while (it.hasNext()) {
HashMap.Entry pair = (HashMap.Entry)it.next();
Log.e(TAG, "#253 : "+pair.getKey() + " = " + pair.getValue());
//it.remove(); // avoids a ConcurrentModificationException
}
}
In your method printMap(), the last statement in the while block is
it.remove(); // avoids a ConcurrentModificationException
This statement may not cause an Exception but it removes the current entry from the HashMap. So after executing
printMap(tableList);
in the Constructor of ExpandableListViewAdapterDemo, the tableList will be empty.
Actually I have one filtered array. I want to store that ArrayList in another ArrayList, but it is not adding. I am saving one model to another. because I want only that filteredlist.
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ComboViewHolder> {
private ArrayList<Products> catList;
private ArrayList<FilteredCategorymodel> filterList;
Context context;
int count = 0;
// ArrayList<FilteredCategorymodel> filterModel;
SharedPrefrences sharedPrefrences;
boolean isClicked = true;
public ProductAdapter(Context context, ArrayList<Products> catList) {
this.catList = catList;
this.context = context;
}
#Override
public ComboViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).
inflate(R.layout.combo_list_item, parent, false);
return new ComboViewHolder(itemView);
}
#Override
public void onBindViewHolder(final ComboViewHolder holder, final int position) {
final Products products = catList.get(position);
Log.e("Products Items::::", products + "");
holder.mProductName.setText(products.getProduct_name());
holder.mProductDescription.setText(products.getProduct_description());
holder.mDescription.setText(products.getRecipe_method());
holder.mPrice.setText(products.getPrice());
Picasso.with(context)
.load(Constants.Image_Path + products.getProduct_image())
.placeholder(R.drawable.common_signin_btn_icon_focus_light) // optional
.error(R.drawable.common_signin_btn_icon_dark) // optional
.into(holder.mPImage);
holder.mPImage.setTag(holder);
holder.btnIncrese.setTag(position);
holder.btnDecrese.setTag(position);
holder.btnIncrese.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int mPosition = (int) v.getTag();
Log.e("mPosition~", mPosition + "~" + position);
count = catList.get(mPosition).getCount() + 1;
for (int i = 0; i < catList.size(); i++) {
filterList = new ArrayList<FilteredCategorymodel>();
filterList.add(catList.get(i));
}
basketCount = basketCount + 1;
catList.get(mPosition).setCount(count);
holder.mQuantity.setText(Integer.toString(products.getCount()));
ProductActivity.updateSum(basketCount);
}
});
holder.btnDecrese.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// int position = (Integer) v.getTag();
int mPosition = (int) v.getTag();
if (catList.get(mPosition).getCount() < 1) {
holder.mQuantity.setText("0");
} else {
count = catList.get(mPosition).getCount() - 1;
basketCount = basketCount - 1;
catList.get(position).setCount(count);
Log.e("COUNT::::", count + "");
holder.mQuantity.setText(Integer.toString(products.getCount()));
ProductActivity.updateSum(basketCount);
// sharedPrefrences = new SharedPrefrences();
// sharedPrefrences.addFavorite(context, catList.get(mPosition));
// Toast.makeText(context, "Fave",
// Toast.LENGTH_SHORT).show();
// Log.e("COUNT::::", count + "");
}
}
});
}
#Override
public int getItemCount() {
return catList.size();
}
Because every time you create new arraylist in loop.
Do it in this way.
holder.btnIncrese.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int mPosition = (int) v.getTag();
Log.e("mPosition~", mPosition + "~" + position);
count = catList.get(mPosition).getCount() + 1;
filterList = new ArrayList<FilteredCategorymodel>();
for (int i = 0; i < catList.size(); i++) {
filterList.add(catList.get(i));
}
basketCount = basketCount + 1;
catList.get(mPosition).setCount(count);
holder.mQuantity.setText(Integer.toString(products.getCount()));
ProductActivity.updateSum(basketCount);
}
});
From this too less information, I guess You are trying to add some values to Your filterList. The problem is, that everytime Your are going through the loop, You are creating a new ArrayList:
for (int i = 0; i < catList.size(); i++) {
filterList = new ArrayList<FilteredCategorymodel>();
filterList.add(catList.get(i));
}
You have to init the filterList first, don´t do this inside the loop. Your loop must look like this:
for (int i = 0; i < catList.size(); i++) {
filterList.add(catList.get(i));
}
it´s also important what You trying to reach. If You just want to fill a new list if the button is clicked, then init Your list inside onButtonClick outside the loop. But if You want to fill that list again and again and the values should persist, then init the list inside Your constructor.
But also, in Your case, this will not work, because filterList is from type "FilteredCategoryModel" and catList is from type "Product". You cannot fill an ArrayList with a wrong type.
If you want to add one ArrayList data into another you don't need to use loop, Use addAll() of ArrayList. Please check below example.
ArrayList<YourClass> a = new ArrayList<>();
ArrayList<YourClass> b = new ArrayList<>();
b.addAll(a);
It will add all data of b into a.
I use following function to animate filtering a list (actually I once found that somewhere, don't know where anymore):
public void animateTo(List<T> items) {
applyAndAnimateRemovals(items);
applyAndAnimateAdditions(items);
applyAndAnimateMovedItems(items);
}
private void applyAndAnimateRemovals(List<T> newItems) {
for (int i = mListItems.size() - 1; i >= 0; i--) {
final T item = mListItems.get(i);
if (!newItems.contains(item)) {
removeItem(i);
}
}
}
private void applyAndAnimateAdditions(List<T> newItems) {
for (int i = 0, count = newItems.size(); i < count; i++) {
final T item = newItems.get(i);
if (!mListItems.contains(item)) {
addItem(i, item);
}
}
}
private void applyAndAnimateMovedItems(List<T> newItems) {
for (int toPosition = newItems.size() - 1; toPosition >= 0; toPosition--) {
final T item = newItems.get(toPosition);
final int fromPosition = mListItems.indexOf(item);
if (fromPosition >= 0 && fromPosition != toPosition) {
moveItem(fromPosition, toPosition);
}
}
}
public T removeItem(int position) {
final T item = mListItems.remove(position);
notifyItemRemoved(position);
return item;
}
public void addItem(int position, T item) {
mListItems.add(position, item); // <- EXCEPTION IS THROWN HERE
notifyItemInserted(position);
}
public void moveItem(int fromPosition, int toPosition) {
final T model = mListItems.remove(fromPosition);
mListItems.add(toPosition, model);
notifyItemMoved(fromPosition, toPosition);
}
Sometimes I get an exception like following in the addItem function:
java.lang.IndexOutOfBoundsException: Invalid index 203, size is 201
Actually, how can this happen? The loop in applyAndAnimateAdditions begins at 0, adds items one by one if they are not already in the list. How can the index exception occur?
You can add this to check if the position is equal or larger(>=) to the ArrayLists size just add the item to the end of the Arraylist.
public void addItem(int position, T item) {
if(position >= mListItems.size())
mListItems.add(mListItems.size()-1, item);
else
mListItems.add(position, item);
notifyItemInserted(position);
}
So here's your problem you are iterating through newItems but you are adding to mListItems