How to Iterate over entire android listview - java

I have a listview where user choose how much for each item he wants, so I need to iterate over each row to get the name (Ovo, Presunto, Queijo, etc), the quantity (the number between the "+" and "-" buttons) and the price. This is already working fine, but I have the following problem: If you look at the bottom of the listview you can know that there are more items, in this picture there are 9 items, but there are 15, and if the user scrolls I will can not iterate over the "hidden" items of listview.
Today I have this code, where I try iterate over the elements of listview:
for (int i = 0; i < listView.getCount(); i++) {
v = listView.getChildAt(i);
if(v != null){
value = (TextView) v.findViewById(R.id.edOptionValue);
nome = (TextView) v.findViewById(R.id.tvOptionName);
tvPrice = (TextView) v.findViewById(R.id.tvPrice);
String price = tvPrice.getText().toString();
//more code here
}
}
listView.getCount() gets the correct number of items (15 items), but when i==10 listView.getChildAt(i) is getting null.
Is there some way to iterate over all items of a listview, incluing the "hidden" elements ?

You should not iterate the list views, instead you should keep all that data (price/quantity) in a list and iterate over that if you really need to do that. That list can be used to populate the ListView as well.

Related

How can I get and set a string resource dynamically in a for-loop using a findViewById() method?

In my app, I want a counter from 0 to 8 to decide the number of players in a game.
Below there are 8 possible fields to write a name inside, which are all set to invisible. If the players-counter is set to 3 players, there should be the first 3 fields visible. Depending on the actual number of the counter, the visibility of the fields changes (1player = first field, 5 players = first 5 fields).
When the +1 (player) button is clicked, a certain method is activated. I tried to run a for-loop everytime the button is clicked. In this for-loop from 0 to "whatever amount" (max. 8 players) the actual fields should be found with "findById" and set to visible.
I tried it with a string resource (.xml) and I can get the text of the resource but with my thought process, I have to update the string resource to every number of the field (if 3 players: "field_" + "1", "field_" + "2", "field_" + "3").
How can I get and (most importantly) set/update a string resource for this specific purpose?
(Switch is too inefficient and I can't use a string with the findViewBy Id()-method by updating the String (not string resource) like mentioned before.
Please help, and accept the fact that I'm new to Android Studio for one week!)
You can use "getIdentifier" which takes a String parameter. So you can set the type as "id" in the second parameter of this method. This method returns the id of the view you want, but beware, it will throw a "FATAL EXCEPTION" if the id of the View doesn't exist. With this id, you can use findViewById to fetch the TextView and change its visibility. The "getIdentifier" method can be called from the "getResources()" method.
Below you can see what it would be like to make visible a TextView that has the id "textView1":
int id = getResources().getIdentifier("textView1", "id", getPackageName());
TextView textView = findViewById(id);
textView.setVisibility(View.VISIBLE);
Below you can see how you would make 8 TextView with id 1 to 8 visible:
TextView textView;
for (int i = 1; i <= 8; i++) {
int id = getResources().getIdentifier("textView" + i, "id", getPackageName());
textView = findViewById(id);
textView.setVisibility(View.VISIBLE);
}
So, just put the limit at i <= x , with x being the limit of players who will play:
TextView textView;
for (int i = 1; i <= totalPlayers; i++) {
int id = getResources().getIdentifier("textView" + i, "id", getPackageName());
textView = findViewById(id);
textView.setVisibility(View.VISIBLE);
}
Do you just want to make some EditTexts visible and others not? Personally I'd keep it simple, do the lookups once (in onCreate or wherever) and store the references in a list. Then when you need to display n fields, you can just iterate over the list and set the first n to VISIBLE and the rest to INVISIBLE.
I feel like it's fine to just list all the EditText IDs (R.id.field_1 etc) and generate your list of actual Views from that, but if that repetition bothers you, there's a few things you could do. Like:
set a tag attribute on each field in the XML, and use findViewWithTag to look them up, generating the lookup strings programmatically, like "field_" + i
do a similar thing with the resource ID, like in #Moises's answer
lookup their containing layout, use getChildCount and [getChildAt] to iterate over the views in that layout, and use isInstance to collect all the EditTexts in order3
create and add the EditTexts in code - you probably don't want to do this, but you could!
I'm not really sure what you mean about the string resource or what you're trying to do - I'd honestly just make a list of R.id.field_1 etc, iterate over that to do findViewById on each and store those in a new list, and you're done. Also my Java's a bit rusty so sorry no example code!

Hashmap get tag crashes

I have an array named checkBox that contains checkboxes items in my xml. I also have a HashMap that stores the value of each of the checkboxes in Double.
Now the problem is when I try to getTag() inside the loop that checks the selected checkboxes by user, it crashes without error shown. I do not understand what went wrong.
double priceSum= 0.0;
for (CheckBox cb:checkBoxes) {
cb.setEnabled(true);
if (cb.isChecked()) {
count++;
toppingsSelection.add(cb); //adding selected items into arrayList
}
}
for (CheckBox items: toppingsSelection) {
text = text + items.getText().toString()+ ", ";
priceSum += hashMap.get(items.getTag()); //THIS CAUSES CRASHING
}
toppings.setText(text); displaying texts of checkboxes checked
price.setText(Double.toString(priceSum));
This is my hashmap:
hashMap.put("chkCheese", 2.50);
hashMap.put("chkPep", 3.50);
hashMap.put("chkChick", 2.00);
hashMap.put("chkBeef", 4.00);
hashMap.put("chkBlackOlives", 2.00);
hashMap.put("chkPine", 1.00);
hashMap.put("chkMushroom", 1.00);
It was a rookie mistake, I have to set tags to my checkboxes in my XML file

Android studio - add array to arraylist? Or similar method to store value pairs/arrays?

This is sort of what I'm trying to do:
ArrayList<int[]> list = new ArrayList<>();
list.add([1,2,3,4];
list.add([5,6,7,8]);
list.add([10,15,-58,39]);
Basically, I have four values that I want to store together in one row, but only temporarily so I don't want to create a data base.
Then I want to send these value pairs to another method and access them there.
This is what I'm doing now:
//I send searchClause, selecArgs, and allHands (int) to a method that queries my db. From there I retrieve 4 values in form of a list.
//I then add these values (average, hands, hand percentage, win percentage) to four different lists. I then repeat this process undefined times.
list = dbCalculations(searchClause, selectionArgs, allHands);
avgArray.add(list.get(0));
handsArray.add(list.get(1));
handPercArray.add(list.get(2));
winPercArray.add(list.get(3));
Then I send these arrays to a new method to inflate a table.
tableInflater(actionsArray, handsArray, handPercArray, winPercArray, avgArray, tableLayout);
I can then access them with a for loop (actionsArray.get(i), handsArray.get(i).) and then direct them to the textviews in my table:
for (int i = 0; i < actions.size(); i++) {
TableRow tableRow = (TableRow) mActivity.getLayoutInflater().inflate(R.layout.tablerow_post_stats, null);
tv = (TextView) tableRow.findViewById(R.id.table_action);
tv.setText(actions.get(i));
tv.setTextColor(Color.BLACK);
tv = (TextView) tableRow.findViewById(R.id.table_hands);
tv.setText(Integer.toString(hands.get(i)));
tv.setTextColor(Color.BLUE);
tv = (TextView) tableRow.findViewById(R.id.table_handPerc);
tv.setText("(" + Integer.toString(handPerc.get(i)) + "%)");
tv = (TextView) tableRow.findViewById(R.id.table_winPerc);
tv.setText(Integer.toString(winPerc.get(i)) + "%");
tv = (TextView) tableRow.findViewById(R.id.table_avg);
tv.setText(avg.get(i) + "$");
if (avg.get(i) >= 0) {
tv.setTextColor(ContextCompat.getColor(mContext, R.color.colorPositive));
} else tv.setTextColor(ContextCompat.getColor(mContext, R.color.colorNegative));
tableLayout.addView(tableRow);
}
I want to find an alternative/short cut to it.

Switching values in spinner based on values in ArrayList

I have an Array list which is generated dynamically, it has a capacity to store 5 elements in all. Now this arraylist can contain 2,3,4,5,6 as elements at all. Sometimes some of these elements might be missing as it is generated dynamically. I want to switch positions in the Spinner based in the array list on a button click. How do I keep track of which element is displayed and move to next element?
For example in onCreate I detect the first element of the Arraylist if that is 2 I set
spin.setSelectedItem(aList.get(1));
The above sete my selection to 2 in the spinner.
on Button Click I want to switch to the next element in the list - The problem here is that the next element can be present or not I use the following check:
if ((spin.getSelectedItemPosition()) < Integer.valueOf(pages.get(pages.size()-1)))
But now how set Spinner value to the next element in the above if condition?
EDIT
Currently I am doing something like:
int current = spin.getSelectedItemPosition();
int nextPos = (pages.indexOf(String.valueOf(current)))+1;
spin.setSelection(Integer.valueOf(pages.get(nextPos)));
where spin is my spinner and pages is the arraylist I have.
You can simply use current index and use setSelection method like this:
public void showNext(View v){
int nextIndex = sp.getSelectedItemPosition()+1;
if(nextIndex < spItems.size())
{
sp.setSelection(nextIndex);
}
}
If you don't want to use getSelectedItemPosition directly, you can keep a global integer variable, currentIndex, and set it in onItemSelected method of spinner. And use that in button click method.
Hope it helps.

Remove List Items and displace the others

I have a List of Buttons and I want to delete the first and the second item. Can i move the rest of Buttons in the List so that the third Button is now the first, the 4th the second and so on?
for(int i = 0; i<nleer; i++){
LinearLayout temp = layoutList.get(letzte);
int tempid = nextButtons.get(i).getId();
CharSequence temptext = nextButtons.get(i).getText();
leerButtons.add(new Button(this));
leerButtons.get(i).setOnClickListener(this);
leerButtons.get(i).setEnabled(true);
leerButtons.get(i).setId(tempid);
leerButtons.get(i).setText(temptext);
leerButtons.get(i).setLayoutParams(new LayoutParams(myButtons.get(i).getWidth(), LayoutParams.WRAP_CONTENT));
tempor.addView(leerButtons.get(i));
nextButtons.remove(i);
at the end i remove the Items (often i = 2) and after this loop i want to use the 3rd Item of the List but i don't know how to move them.
If you have a List x, and you do x.remove(0) to remove the first item, the index of the first item remains 0 (all items shift forward one position). It sounds like you're asking for the default list class behavior.

Categories