How to check if new added item exist in recyclerView? - android

Actually i'm developing an inventory app where i scan some EAN codes then i insert the quantity of an item and then i add it to an ArrayList in recyclerView.
For now i had no problem as i've made the inventory part where the items had to have different lines for each in recyclerView but now i have to make the order part and here if an item exist yet in ArrayList i have to sum it's quantity and put it to top of recyclerView.
I was trying to make something like a for loop when i'm going to add a new item and check if it's exist in ArrayList, if it's exist i was going to sum that item quantity with old one but the problem was that sometimes the app was going to crash and that the item wasn't going on top of recyclerView.
Do you have any suggestion on how can i do it?
for (ItemModel item : itemModel) {
if (item.getCodiceArticolo()
.equals(code.getText()
.toString())) {
item.setQta(String.valueOf(
Integer.parseInt(item.getQta()) + 1));
}
}
I was trying to make something like that.

Try this code:
ItemModel matchedItem = null;
int matchedItemIndex = -1;
for (ItemModel item : itemModel) {
if (item.getCodiceArticolo()
.equals(code.getText()
.toString())) {
item.setQta(String.valueOf(
Integer.parseInt(item.getQta()) + 1));
matchedItem = item;
matchedItemIndex = itemModel.indexOf(item);
break;
}
}
if (matchedItemIndex > -1) {
itemModel.remove(matchedItem);
itemModel.add(
0,
matchedItem);
notifyItemMoved(index,
0);
}

You do not adderror log to your list, so I guess your program crashes because sometimes there is a value that has no quantity (there is no valid number) and therefore can not parse the number, so in this case you just write that there is one item in list that has not been there yet.
for (ItemModel item : itemModel) {
if (item.getCodiceArticolo()
.equals(code.getText()
.toString())) {
try {
item.setQta(String.valueOf(
Integer.parseInt(item.getQta()) + 1));
}
catch (Exception ex) {
item.setQta(String.valueOf(1));
}
}
}
If this does not help, please attach error log.

Since the app is crashing, your ArrayList might not have been initialized as suggested in the comments.
For checking if the item exists you can use
if (arraylist_of_items != null && arraylist_of_items.contains(item)) {
// do your stuff here
}

Three days a go i was getting the "ConcurrentModificationException" but now i'm trying another approach inspired by other answers or better the following one:
boolean nuovo = true;
for (ItemModel itemModels : itemModel) {
if (itemModels.getCodiceArticolo()
.equals(code.getText()
.toString())) {
itemModels.setQta(String.valueOf(
Integer.parseInt(itemModels.getQta()) + 1));
nuovo = false;
break;
}
}
if (nuovo) {
itemModel.add(new ItemModel(
code.getText()
.toString(),
"1"));
}
And is not crashing anymore and seems to work fine.
Thank's all for suggestions.
UPDATE
THANKS TO kartik malik ANSWER i was able to even "update" my items by adding the last one added on top, as i'm using reverse recyclerView i've done it by this wasy instead of putting the item to position 0
ItemModel matchedItem = null;
int matchedItemIndex = -1;
boolean nuovo = true;
for (ItemModel itemModels : itemModel) {
if (itemModels.getCodiceArticolo()
.equals(code.getText()
.toString())) {
itemModels.setQta(String.valueOf(
Integer.parseInt(itemModels.getQta()) +
Integer.parseInt(qta.getText()
.toString())));
MediaPlayer mpFound = MediaPlayer.create(
OrdiniActivity.this,
R.raw.errorsound);
mpFound.start();
matchedItem = itemModels;
matchedItemIndex = itemModel.indexOf(itemModels);
nuovo = false;
break;
}
}
if (matchedItemIndex > -1) {
itemModel.remove(matchedItem);
itemModel.add(matchedItem);
}
if (nuovo) {
itemModel.add(new ItemModel(
code.getText()
.toString(),
qta.getText()
.toString()));
}
With the boolean i'm checking if the item exist or not and if it doesn't exist i add the item as a new one.

Related

How can I update key values in realtime database?

I want to update key values when it removed, so I wrote codes below. These codes are in the Checkbox listener.
What I did first :
if(isChecked) {
Long size = dataSnapshot.child("Bookmark").getChildrenCount();
ref_h.child(userUid).child("Bookmark").child(Long.toString(size + 1)).setValue(diningUid);
} else {
for (int i = 1; i <= dataSnapshot.child("Bookmark").getChildrenCount(); i++) {
if (dataSnapshot.child("Bookmark").child(Integer.toString(i)).getValue().toString().equals(diningUid)) {
dataSnapshot.child("Bookmark").child(Integer.toString(i)).getRef().removeValue();
isRemoved = true;
}
if(isRemoved) {
if(i != dataSnapshot.child("Bookmark").getChildrenCount()){
String newDiningUid;
newDiningUid = dataSnapshot.child("Bookmark").child(Integer.toString(i + 1)).getValue().toString();
Log.d("newUID", newDiningUid);
ref_h.child(userUid).child("Bookmark").child(Integer.toString(i)).setValue(newDiningUid);
} else {
dataSnapshot.child("Bookmark").child(Integer.toString(i)).getRef().removeValue();
}
}
}
}
But when the Checkbox status changes rapidly, key values are messed up.
like this
data structure 2
Then I fixed the code with try-catch phrase.
if(isChecked) {//if not checked before listener runs, add to bookmark
Long size = dataSnapshot.child("Bookmark").getChildrenCount();
ref_h.child(userUid).child("Bookmark").child(Long.toString(size + 1)).setValue(diningUid);
} else {//if checked before listener runs, remove from bookmark
for (int i = 1; i <= dataSnapshot.child("Bookmark").getChildrenCount(); i++) {
try {
if (dataSnapshot.child("Bookmark").child(Integer.toString(i)).getValue().toString().equals(diningUid)) {
dataSnapshot.child("Bookmark").child(Integer.toString(i)).getRef().removeValue();
isRemoved = true;
}
} catch (NullPointerException e) {
if (dataSnapshot.child("Bookmark").child(Integer.toString(i + 1)).getValue().toString().equals(diningUid)) {
dataSnapshot.child("Bookmark").child(Integer.toString(i + 1)).getRef().removeValue();
isRemoved = true;
}
}
if(isRemoved) {
//update afterward value's index
if(i != dataSnapshot.child("Bookmark").getChildrenCount()){
String newDiningUid;
newDiningUid = dataSnapshot.child("Bookmark").child(Integer.toString(i + 1)).getValue().toString();
ref_h.child(userUid).child("Bookmark").child(Integer.toString(i)).setValue(newDiningUid);
} else {//remove last value
try {
dataSnapshot.child("Bookmark").child(Integer.toString(i)).getRef().removeValue();
} catch (NullPointerException e) {
dataSnapshot.child("Bookmark").child(Integer.toString(i + 1)).getRef().removeValue();
}
}
}
}
}
But I don't think I solved this problem.
How can I update key values properly?
or do I need to add a delay to Checkbox?
or change the data structure?
The best solution is to not use sequential numeric keys, but rely on Firebase's push IDs. For reasons on why this is a better approach and how they work, see these classic Firebase blog posts:
Best Practices: Arrays in Firebase
The 2^120 Ways to Ensure Unique Identifiers
If you insist on using array-like keys, you will have to use a transaction on the entire bookmark node to determine the next index. This is the only way to prevent the race condition that you now encounter when the array contents frequently change.

How to select multiple Checkbox and create an Array with the values in android

I have added 9 CheckBox in my Fragment which is getting checked
according to the response from JSON. If user wants to update his/her
profile, He/she can check/uncheck any of them. Now I have to confirm
that how many of them are checked and create an Array as a
parameter according to that. I am not using any adapter for that.
please let know how to set the condition to get the value of only
checked checkboxes
I am trying to do like this
cb_prfl_setng_general=(CheckBox)rootView.findViewById(R.id.cb_prfl_setng_general);
cb_prfl_setng_economics = (CheckBox)rootView.findViewById(R.id.cb_prfl_setng_economics);
cb_prfl_setng_business=(CheckBox)rootView.findViewById(R.id.cb_prfl_setng_business);
cb_prfl_setng_social=(CheckBox)rootView.findViewById(R.id.cb_prfl_setng_social);
cb_prfl_setng_politics=(CheckBox)rootView.findViewById(R.id.cb_prfl_setng_politics);
cb_prfl_setng_entertainmnt=(CheckBox)rootView.findViewById(R.id.cb_prfl_setng_entertainmnt);
cb_prfl_setng_technology=(CheckBox)rootView.findViewById(R.id.cb_prfl_setng_technology);
cb_prfl_setng_spritual=(CheckBox)rootView.findViewById(R.id.cb_prfl_setng_spritual);
cb_prfl_setng_sports=(CheckBox)rootView.findViewById(R.id.cb_prfl_setng_sports);
if(cb_prfl_setng_general.isChecked()){
String[] Interest = {"catagory_id=1"};
}else if(cb_prfl_setng_economics.isChecked()){
String[] Interest = {"catagory_id=1","catagory_id=2"};
}else if(cb_prfl_setng_general.isChecked()){
String[] Interest = {"catagory_id=1","catagory_id=2","catagory_id=3"};
}else if(cb_prfl_setng_entertainmnt.isChecked()){
String[] Interest = {"catagory_id=1","catagory_id=2","catagory_id=3","catagory_id=4"};
}
But I don't think this is the right way to get the exact value.
You need to test each checkbox separately and accumulate the category ids:
List<String> interestList = new ArrayList<String>();
// for each checkbox checked, accumulate a category id in the list
if (cb_prfl_setng_general.isChecked()) {
interestList.add("catagory_id=1");
}
if (cb_prfl_setng_economics.isChecked()) {
interestList.add("catagory_id=2");
}
if (cb_prfl_setng_general.isChecked()) {
interestList.add("catagory_id=3");
}
if (cb_prfl_setng_entertainmnt.isChecked()) {
interestList.add("catagory_id=4");
}
.
.
.
// convert the list into an array
String[] interest = interestList.toArray(new String[interestList.size()]);
System.out.println("interest");
for (String str : interest) {
System.out.println(str);
}
String WeekDays="";
List DayList = new ArrayList();
if (cbSunday.isChecked()) {
DayList.add(String.valueOf(cbSunday.getText()));
}
if (cbMonday.isChecked()) {
DayList.add(String.valueOf(cbMonday.getText()));
}
if (cbTuesday.isChecked()) {
DayList.add(String.valueOf(cbTuesday.getText()));
}
if (cbWednesday.isChecked()) {
DayList.add(String.valueOf(cbWednesday.getText()));
}
if (cbThursday.isChecked()) {
DayList.add(String.valueOf(cbThursday.getText()));
}
if (cbFriday.isChecked()) {
DayList.add(String.valueOf(cbFriday.getText()));
}
if (cbSaturday.isChecked()) {
DayList.add(String.valueOf(cbSaturday.getText()));
}
String[] Days = DayList.toArray(new String[DayList.size()]);
WeekDays="";
for (String str : Days) {
if(WeekDays.equals(""))
{
WeekDays=WeekDays+str;
}
else {
WeekDays = WeekDays + "," + str;
}
WeekDays=WeekDays;
Log.d("LogDays",WeekDays);
}

Java, what is best way to compare two lists?

I have two lists of Default and Chrome browsers history.
I want to merge these two lists into one list.
I need to update item if I find it duplicate (is common between two lists).
So, my "BrowserRecord" class is like this:
public class BrowserRecord {
private long id;
private int bookmark;
private long created;
private long date;
private String title;
private String url;
private long visits;
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BrowserRecord record = (BrowserRecord) o;
return url.equals(record.url);
}
#Override
public int hashCode() {
return url.hashCode();
}
// other getter setter methods
...
}
and finally, I have a method that gets browsers histories and does merging:
public List<BrowserRecord> getHistory() {
List<BrowserRecord> browserList = new ArrayList<BrowserRecord>();
// get history of default and chrome browsers
List<BrowserRecord> defaultList = getDefaultBrowserHistory();
List<BrowserRecord> chromeList = getChromeBrowserHistory();
Log.e(TAG, "=> size of Default browser:" + defaultList.size());
Log.e(TAG, "=> size of Chrome browser:" + chromeList.size());
// compare list A with B, update A item if equal item found in B and push it to tempList
for(int i=0; i<chromeList.size(); i++) {
BrowserRecord chromeBrowser = chromeList.get(i);
for(int j=0; j<defaultList.size(); j++) {
BrowserRecord defaultBrowser = defaultList.get(j);
if(chromeBrowser.equals(defaultBrowser)) {
if(chromeBrowser.getBookmark() != defaultBrowser.getBookmark())
chromeBrowser.setBookmark(1);
chromeBrowser.setVisits(chromeBrowser.getVisits() + defaultBrowser.getVisits());
}
}
browserList.add(chromeBrowser);
}
// compare list B with A, jump if equal item found in A, push to tempList if item not found
for(int i=0; i<defaultList.size(); i++) {
BrowserRecord defaultBrowser = defaultList.get(i);
boolean found = false;
for(int j=0; j<chromeList.size(); j++) {
BrowserRecord chromeBrowser = chromeList.get(j);
if(defaultBrowser.equals(chromeBrowser)) {
found = true;
break;
}
}
if(!found)
browserList.add(defaultBrowser);
}
Log.e(TAG, "=> size of final browser:" + browserList.size());
return browserList;
}
I have tested this method and is working fine. Since my history records on mobile device after 3 years didn't exceed more than 200 records on one list and 150 for others, I assume something similar is happening for other users. But I'm sure is not optimum way.
What do you recommend?
any suggestion would be appreciated. Thanks.
Not sure I understand correctly, but it seems like what you're trying to do is, given both lists, create a final list which will contain all of the elements from both lists, removing any duplicates.
If this is the case, then take a look at Java's TreeSet class. If you iterate over all of the elements from both your lists and insert them into a TreeSet, you will basically get the result you're looking for. You can then use an Iterator to create an ArrayList containing all of the non-duplicate items from both your lists. As a side-effect of using a TreeSet, they will ordered (you can also use either a HashSet if you don't care about the order or a LinkedHashSet if you want to preserve the order of insertion).

Monodroid ListView get selected item typecast error

I have this problem with listview item and hoping that you guys can help me fix this.
My goal is to fill listview with list and when user touches one these items, i want to have another view loaded. Adding items works fine, but when i get the value from selected item and typecast it to the correct object, it comes with " ‘invalid cast’ cannot cast..." and crashes.
FYI, I use the Android 4.0 sim, and these are part of the code:
SetContentView(Resource.Layout.ArchiveList);
ListView lstArchiveList = FindViewById<ListView>(Resource.Id.lstArchive);
if (lstArchiveList != null) {
ArrayAdapter<MobileContracts.Archive> archivesAdapter = new
ArrayAdapter<MobileContracts.Archive>(this, Resource.Layout.ListItem, sessionData.Archives.Archive);
lstArchiveList.Adapter = archivesAdapter;
lstArchiveList.TextFilterEnabled = true;
lstArchiveList.ItemClick += new EventHandler<AdapterView.ItemClickEventArgs>(lstArchiveList_ItemClick);
archivesAdapter.NotifyDataSetChanged();
}
OnClick event handler:
void lstArchiveList_ItemClick(object sender, AdapterView.ItemClickEventArgs e) {
SetContentView(Resource.Layout.SearchDocuments);
ListView lstEditableIndexList = FindViewById<ListView>(Resource.Id.lstEditableIndexList);
if (lstEditableIndexList != null) {
Console.WriteLine("sender type: {0}", sender.GetType().FullName);
Object currentItem = e.Parent.GetItemAtPosition(e.Position);
MobileContracts.Archive selectedArchive = (MobileContracts.Archive) currentItem; //invalid cast?
Toast.MakeText(Application, selectedArchive.Name + " => " + selectedArchive.Id, ToastLength.Short).Show();
}
Any help appreciated. Thank's a lot in advance.
Cheers, Inoel
Never mind, I figure this out.
Replace this:
MobileContracts.Archive selectedArchive = (MobileContracts.Archive) currentItem; //invalid cast?
with this:
System.Reflection.PropertyInfo propertyInfo = currentItem.GetType().GetProperty("Instance");
MobileContracts.Archive selectedArchive = propertyInfo.GetValue(currentItem, null) as MobileContracts.Archive;

Android App- Using a loop for setText procedure to populate EditText

Trying to use a loop to set the text of 12 checkboxes from a db query. Would like to substitute "add1" with an array value and loop through all 12 instead of spelling out each one. Any ideas of how to do this?
Here is the code I am trying to modify:
add1Text= (CheckBox) findViewById(R.id.add1);
if (cursor.getString(cursor.getColumnIndex("add1")) == null) {
add1Text.setVisibility(View.GONE);
}
else {
add1Text.setText(cursor.getString(cursor.getColumnIndex("add1")));
}
Please note: everything below is off the top of my head, I can't test it right now. I'll test it later when I get a chance.
I think you'll need to keep track of which column to associate with each CheckBox... I'm presuming it's something like this:
Column: add1 => Checkbox: add1Text
Column: add2 => Checkbox: add2Text
and so on and so forth.
In this circumstance, you'll need to manually keep track of them, possibly in an array. I'd suggest making a Pair class that you can use. I've altered the class from this post [ A Java collection of value pairs? (tuples?) ]
public class Pair<L,R> {
private final L left;
private final R right;
public Pair(L left, R right) {
this.left = left;
this.right = right;
}
public L getLeft() { return left; }
public R getRight() { return right; }
#Override
public int hashCode() { return left.hashCode() ^ right.hashCode(); }
#Override
public boolean equals(Object o) {
if (o == null) return false;
if (!(o instanceof Pair)) return false;
Pair pairo = (Pair) o;
return this.left.equals(pairo.getLeft()) &&
this.right.equals(pairo.getRight());
}
}
Now, you'll need to make a List (or similar) containing the pairs that you want.
List<Pair<CheckBox, String>> list = new ArrayList<Pair<CheckBox, String>>;
list.add(new Pair<CheckBox, String>((CheckBox) findViewById(R.id.add1), "add1");
list.add(new Pair<CheckBox, String>((CheckBox) findViewById(R.id.add2), "add2");
list.add(new Pair<CheckBox, String>((CheckBox) findViewById(R.id.add3), "add3");
and so on and so forth
Then you can iterate through the List using something like
foreach (Pair<CheckBox, String> item in list)
{
if (cursor.getString(cursor.getColumnIndex(item.getLeft()) == null)
{
item.getRight().setVisibility(View.GONE);
}
else
{
item.getRight().setText(cursor.getString(cursor.getColumnIndex(item.getLeft()));
}
}
Got it! Forgot that I was dealing with objects and also realized I needed a third array. Here is what I came up with.
cList contains column names
fList are the objects (in this case CheckBoxes)
pList are the names of the objects I am selecting from the layout.
Object fList[]={add1Text,add2Text,add3Text};
int pList[]={R.id.add1,R.id.add2,R.id.add3};
cList = cursor.getColumnNames();
for (int i =0; i < fList.length; i++){
fList[i] = (CheckBox) findViewById(pList[i]);
if (cursor.getString(cursor.getColumnIndex(cList[i])) == null) {
((TextView) fList[i]).setVisibility(View.GONE);
}
else {
((TextView) fList[i]).setText(cList[i] + " - " + cursor.getString(cursor.getColumnIndex( cList[i])));
}
}
Sets the CheckBox text to ( Column name - Value )

Categories

Resources