Alright... No one laugh... I am working on an app in MIT/Google Appinventor. Here's a rundown:
Scans a barcode then runs the pictured function.
If the item is in the list then
Find that items position index in the inventory list.
Use that items index, to increment the value in the quantity list by 1.
If the item is not in the list then
Add that item to the inventory, and add a "1" to the quantity.
I can't see why it won't work so I was just checking to see if there are any obvious flaws in my logic. If the logic looks solid, then I should be able to figure out the Appinventor problem to make it work.
Here's your function translated (accurately?) into pseudo-code to help with my own understanding (and hopefully others'):
function addItem:
if inventoryList.contains(scannerResult):
inventoryPosition = inventoryList.positionOf(scannerResult)
quantityPosition = quantityList.positionOf(scannerResult)
quantityItem = quantityList.selectListItemAt(quantityPosition)
quantityList.insert(quantityItem at inventoryPosition)
else
inventoryList.add(scannerResult)
quantityList.add(1)
The problem appears to be in the logic when the scanner result is already in the list. I don't know the relevant app-inventor functions, but I think that you want something more like:
if inventoryList.contains(scannerResult):
inventoryPosition = inventoryList.positionOf(scannerResult)
quantity = quantityList.selectListItemAt(inventoryPosition)
quantityList.setListItemAt(quantityPosition to quantity + 1)
That last line is the bit I don't know how to translate into app-inventor language, but hopefully it's enough to point you in the right direction.
#blahdiblah made a good analysis of the problem.
The solution with App Inventor looks like this: instead of the insert list item block you have to use the replace list item block
Related
Just wondering to check is there any object has isSelected value as true, if so then do a foreach to add the particular object in another list. Is this good way to prevent the foreach or still directly do foreach without any. Because inside the any i can see they do the same foreach. Experts please advice.
final isAnyMainGod = listMainGod.any((element) => element.isSelected);
if (isAnyMainGod) {
listMainGod.forEach((element) {
if (element.isSelected) {
_tempID.add(
FilterData(type: 'MAINGOD', filterValue: element.mainGodNameId));
}
});
}
The issue I see here is that you are doing a potential full iteration of the list, followed up by another full iteration of the list, applying identical logic a second time.
You could do something like this:
var _tempId = listMainGod.where((element) => element.isSelected)
.map((e) => FilterData(type: 'MAINGOD', filterValue: e.mainGodNameId))
.toList();
In the my suggestion, the condition in the where will remove any elements from the list, that don't evaluate to a true. There is still a full iteration of the list (but you'll have to do that anyway at some point), but this suggestion only has 1 full iteration, and a single line of code for the condition (as opposed to your two occurrences of element.isSelected).
Then, the map, is an iteration on only the matching list items, to apply give to the FilterData function.
In the event that no matching elements are found, you are provided a list with 0 elements.
The other added benefit of writing something like this, is it requires less cognitive load, to follow. You don't to know or care if isAnyMainGod exists (or if you have to look and see if it's used elsewhere, because that one spot), you just iterate over any results you have from the result. In my experience, the fewer variables you use to track state results fewer potential places you can introduce bugs.
It's been a while that i'm trying to get an anwser to my problem, but i didn't find it... So i'm searching for your help.
I work on xamarin to make an android application but i dont use Xamarin.Forms (i would have used it, if i knew it when i begin the project
I'll directly to the point, if you have some question, just ask me.
So i got a Listview where i can select 2 or more items :
private void _listViewIntervention_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
_intervention[e.Position].IsSelected = !_intervention[e.Position].IsSelected;
if (_intervention[e.Position].IsSelected)
e.View.SetBackgroundColor(Android.Graphics.Color.Rgb(255, 127, 127));
else
e.View.SetBackgroundColor(Android.Graphics.Color.Rgb(230, 230, 230));
_numberInterventionSelected.Text = _intervention.FindAll(elem => elem.IsSelected == true).Count().ToString();
}
That thing work but if i have a listview with 20 items i.e and i select 3 items, if i scroll the listview, everything will be disturb and my 3 highlighted rows won't be anymore and the highlight will be on another row that i've never select.
I think that not that evident and it might be blur.
IMO i'm not changing the good thing when i do the "e.View.SetBackgroundColor" but i've try lot of thing that never worked.
I might not going the best way to do what i want to do btw.
The result i want is when i scroll the listview, nothing change so i can select the first and the last item of the listview i.e.
I search again in my side but i count a little on you know...
Thanks for reading and have a good day !
I have already getting same problem after lot of search and find the solution
In Xamarin custom adapter remove ViewHolder System it's working fine after removing Holder system
I'm trying to click on a item at a specific position in a grid view.
onData(instanceOf(MyClass.class))
.inAdapterView(withId(R.id.my_view))
.atPosition(R.integer.my_id)
.perform(click());
but I'm getting this java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
I'm queuing the responses using MockWebServer, even after the UI is on screen with all the list item, I'm getting this error, I'm not sure why.
Also, I want to get the content of the specific item.
Well, I think that's because you're matching class which is only one, not a specific adapter with values.
Please consider this post:
The matcher passed as argument to onData() must match the value as
returned by Adapter.getItem(). So the first version doesn't match,
because of the wrong type being used. It should be:
onData(is(instanceOf(IconRowAdapter.IconRow.class)))
What also can be a pitfall is using equalTo on different kinds of
CharSequences. String is a CharSequence, but if IconRow.getText()
returns CharSequence instead of String, then this can also be
Spannable, Editable, etc in which case equalTo wouldn't match. So if
IconRow.getText() return anything but String, make sure to convert it
into a String before comparison.
This post was taken from How to use Espresso to test item in adapter at a specific position
Your question lacks of code of tested class, so I cannot give you direct answer. I can only recommend to read StackOverflow link above.
Hope it help
You may need to "drill down" a little deeper into the view hierarchy to get to the item in the cell. Put an additional method call before the ".perform" using the id of the item in the grid cell
onChildView(withId(R.id.???)).perform(click());
Use the id of the view that the user would click on.
I have an activity that extends ListActivity, a list of "concepts" (let's call this list "C") and an onItemClickListener defined for this list. Whenever I click a "concept", no matter which one, the app must display another list. I have the following code to change the displayed list:
if(position == 0) change_list("adapter1");
else if (position == 1) change_list("adapter2");
else if (position == 2) change_list("adapter3");
else if (position == 3) change_list("adapter4");
else if (position == 4) change_list("adapter5");
Where position is the position of the clicked element in C
The function change_list performs setListAdapter(parameter) depending on the parameter I pass.
If I click the first element of C (the first concept), a list related to the first concept must appear. However, after calling setListAdapter(adapter), the data related to this concept is displayed, and also part of the C's list data.
For example: let's suppose C has these concepts:
A B C D E
and I click "A", which would lead to display a list with the following data: {a1,a2}
That's the final result:
a1 a2 C D E
And then, when I interact with another element on screen or I scroll down the list, the "ghost" data disappears and only the correct data remains on screen, just like this:
a1 a2
To make things worse, when I want to display list C again, nothing strange happens. Everything is displayed correctly.
At any time incorrect data is stored where it doesn't have to. One function my app must allow is to generate a txt file , and the generated txt file contains exactly the data I introduced. No data is corrupted or duplicated. I also tried using notifyDataSetChanged() and other functions, but I didn't solve the problem.
EDIT :
Here goes the xml code used for the main list of the activity:
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#FF0000"
android:layout_below="#+id/afegir"/>
And an example of code in which I determine which contents must be displayed on screen:
else if(comprovar_concepte_actiu() == 1){
pnt = mydbhandler.getStoredValues("despeses1");
pnt.moveToFirst();
if(pnt.moveToFirst()){
do{
adapter_mostrar.add(pnt.getString(pnt.getColumnIndex("nom")));
}while(pnt.moveToNext());
}
adapter_mostrar.notifyDataSetChanged();
}
Where comprovar_concepte_actiu() returns and integer that tells which concept has been clicked in the main list C and adapter_mostrar is the single adapter I'm using now, instead of using multiple adapters (which made me use setListAdapter)
At the beginning of the activity, I call this.setListAdapter(adapter_mostrar). That's all I have.
EDIT 2 :
https://www.dropbox.com/s/7twgy043lkxb2x5/conceptes.java?dl=0
Here is a link to my conceptes.java activity. Press CTRL+F once opened and search "this is where I call.. " and you will directly get to the function where the change of list displayed on screen starts
I haven't found a solution yet. Any idea will be totally appreciated
The problem here is that - when you set a new adapter - the old data is still drawn. In other words, there has been no command to "refresh" the listView. However, the new adapter will be commanded to draw its own views. What ultimately occurs is that the old items are still there, the new items are redrawn, but when scrolled away the new adapter won't redraw/recreate the old items.
The solution is to simply refresh the adapter. However, there are two ways to go about this:
Add a new adapter every time and use myListView.invalidateViews(); or something similar [This is probably the easiest solution to implement, although probably not the best in the long run]
Change the dataset of the adapter and use notifyDataSetChanged() [on the adapter]
The latter option is a far better idea. You should use a single adapter and simply change its data over time. Once its dataset is changed, then tell the adapter that such a thing happened so it refreshes. However, you should read more here on all the different thoughts and processes about it, rather than take my opinion on it.
Edit:
There's apparently some very nicely, thought out answers around. Here's another one, that tells you more specifically about the differences between these two:
Is there any difference between ListView.invalidateViews() and Adapter.notifyDataSetChanged()?
Edit2:
With the onClickListener in mind, invalidateViews() will most likely not work, as it'll probably still draw the old views to "finish" the click (ie, draw the highlighting).
Changing the data directly inside a single adapter and using Adapter.notifyDataSetChanged() is your best bet, as it'll know to redraw everything from a single adapter and use only the current data defined by this single adapter.
Best to leave the data specifics (and defining what to draw based off of that data) up to what actually knows the data, rather than a higher up container that knows nothing specific about the actual data.
I am banging my head for the last couple days in order to get this done but Im unable to. Someone please help me out!
Let me not tell u the whole thing and will try to explain it simply n clearly.
Im having 1 ArrayList. I am trying to replicate that into another one and trying to delete an item at a particular index. But this not only deletes the item in the replicated ArrayList but also the original ArrayList.
For ex:
var DuplicateList:ArrayList = new ArrayList();
DuplicateList = OriginalList;
DuplicateList.removeItemAt(2);
The above not only deletes the "Item 3" at Index-2 in the DuplicateList but also in the OriginalList.
I just need some workaround with this approach as this is the only way by which whatever I typed inside the controls present in an ItemRenderer of a FLEX List control that uses the OriginalList as a dataProvider is RETAINED, when I change the dataProvider of the List Control from OriginalList to DuplicateList. The following approach does not retain all the data.
var DuplicateList:ArrayList = new ArrayList();
DuplicateList.addAll(OriginalList);
DuplicateList.removeItemAt(2);
ListCntrl.dataProvider = DuplicateList;
Thanks for your help in advance...
A very, very important thing to understand:
ActionScript3 uses references to objects. Because of that, the two variables in this line of code refer to the exact same instance of an ArrayList:
DuplicateList = OriginalList;
So, when you remove an item from one reference, it is gone from the next. If you want two separate instances of ArrayList, then you need to clone it like you are suggesting later in your code.
So far, so good... but why is your ListCntrl retaining the data from the OriginalList? That doesn't make any sense at all. If you remove an item from DuplicateList and then use it as the data provider, then that item shouldn't be there. I think there is more to this story...