I have a problem that I don't think can be solved.
I would like to change an ImageView background that is inside a row in a ListView. The row is a custom view with two TextView and an ImageView.
I have the ListView id, the number of the row that contains the ImageView i want to edit and the ImageView id, of course.
There is any way to access the right ImageView?
Thanks for any answer.
UPDATE
Better Explanation:
I have a list of device. They are loaded from an adapter, which takes values from an array.
After the list is created, i start a new activity sending an array which contains the devices address.
The other activity receive the array, scan for devices in range (Bluetooth) and get a list of those.
Then I confront the two array and if there is a device in range, I change the image on the ListView relative to that device. The index of the array is the row number in the ListView.
I don't think I need to post any code since the array sending from an activity to the other is made via Intent and that works. Debugging I have bot the array.
I just need a way to access the image in the row of that list.
I found the solution.
I'll post here the code if someone, some day will have my problem:
// We have the listview, list of online devices and the list of our devices!
// Init ListView
ListView device_list = (ListView) findViewById(R.id.deviceListView);
// Loop for all the online devices found
for (int j = 0; j < mLeDevices.size(); j++){
// Get the online device address
BluetoothDevice device = mLeDevices.get(j);
String deviceAddress = mLeDevices.get(j).getAddress();
// Loop for all the devices in the ListView
for (int i = 0; i < device_address.size(); i++) {
// Compare devices address
if (device_address.get(i).compareTo(deviceAddress) == 0) {
int visiblePosition = device_list.getFirstVisiblePosition();
View v = device_list.getChildAt(i - visiblePosition);
ImageView state = (ImageView) v.findViewById(R.id.item_state);
state.setImageResource(R.drawable.led_on);
}
}
}
The list will have no more than 5 elements, so no problems with the list scrolling and losing the index.
I Actually would like to ask a question. Is it right to assume that the position in the ListView starts from 0? Or the first element index is 1?
If i understand your question right then you can use the following idea
If you know the position of the image view then you can try something like this in your getView method
imageView.setBackground(R.drawable.normalBackground);
if(position==yourRequiredPosition){
imageView.setBackground(R.drawable.newBackground);
}
this way it will always set normalBackground for imageView in each row, but for the yourRequiredposition row newBackground will be set. Only thing is you have to have a way to figure out "yourRequiredPosition"
Related
so I'm currently writing an app for android, and im still a noob in java/android.
Anyways i have this 2 strings, one with names and the other with emails, and i want to output them in a listview with a custom adapter.
It works fine so far but i dont know how to set the items dynamically (with a for loop).
To create the adapter and so on, I used this tutorial:
http://www.ezzylearning.com/tutorial/customizing-android-listview-items-with-custom-arrayadapter
I simply changed the ImageView to a second TextView.
In the tutorials code there are 5 items added to the list, but i need them dynamically, since Im not always having the same amount of name+emails to output
I already tried putting it in a for-loop by doing:
Weather weather_data[] = new Weather[names.length];
for(int z=0; z == names.length){
Weather[z]={new Weather(names[z], emails[z])};
}
I also tried it with adding "new" infront and trying to set everything null before, basically trial&error since i dont know much about it.
So can anyone tell me how I add the items dynamically?
(Ps: sorry if I used wrong names to describe anything)
This should work
Weather weather_data[] = new Weather[names.length];
for(int z=0; z < names.length; z++){
weather_data[z] = new Weather(names[z], emails[z]);
}
Give this a read to learn how for loops work
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html
and this one for arrays
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
try this
ArrayList<Weather> weatherData = new ArrayList<>();
for (int i=0; i < names.length(); i++){
weatherData.add(new Weather(names[i], emails[i]));
}
Then when you need it as a Weather[] use weatherData.toArray()
I have a ListView that uses a custom layout that has 5 child View objects (4 TextView and 1 CheckBox) in the custom layout. Only the TextViews are bound, however - the CheckBox has no corresponding field in the database. The purpose of the CheckBox is simply to identify which of the items being displayed I would like to process in "the next step". I'm using a custom ViewBinder to assign the text values correctly (because some of the values from the DB are dates, etc).
Part of the user interface is three buttons - 'All', 'None', and 'Invert' that I use to toggle the status of each item in the list. For the 'All' button, for example, I do this with the following code (which I now know is NOT correct - I include it to show what I'm trying to do):
ListAdapter la = getListAdapter();
ListView lv = getListView();
int iCount = la.getCount();
for(int i=0; i<iCount; i++)
{
View vv = lv.getChildAt(i);
CheckBox cb = (CheckBox) vv.findViewById(R.id.ledgerItemCheckBox);
cb.setChecked(true);
}
This works fine as long as the number of items in the list doesn't exceed the list size so that all items are always visible. When I exceed that number, though, the 'getChildAt' function sometimes returns null because (if I understand correctly) it isn't meant to return all of the items in the list, only those items that are visible, which results in a NullPointerException.
How can I properly set the CheckBox on all views, even if they aren't visible?
Create a pseudo binding to one of your TextView data, create an ArrayList of Boolean objects as your back end for the checkboxes. Please note an ArrayList may not be the best data structure for your application. Fill the ArrayList with booleans set to the initial value of the corresponding position of your Cursor's data set. When you're binding use the ArrayList as the back end data. When you select all, none, or invert, update the Boolean objects in the ArrayList then call notifyDataSetChanged() on your SimpleCursorAdapter.
Addition ah, the other half of the problem, yes, use the onClickListener for the CheckBoxes but use the same listener, don't create a new object for each. Use the getPositionForView() method to get your position and update the underlying data.
I have a ListView that's being populated from a custom CursorAdapter. Every item(-row) has a checkbox.
A couple of important facts before I explain the problem:
A. The checked/unchecked data is coming from the DB.
B. I save the location of every "checkbox" to a boolean array.
C. There is no way to know which checkbox is checked, without re-querying the until I scroll to it, since it is not loaded yet.
Problem is:
I am trying to create a "Clear All" button. for every "checked" checkbox, I will have to update the column in the DB to "no".
I tried LV.scrollTo(lastItem), and then check if each row is checked or not:
for (int i = 0; i < cursor.getCount(); i++) {
boolean t = itemChecked.get(i); //check the array to see if this row is checked
if (t == true) {
//set to "no" in the DB
}
but it seemed that it "skipped" over the rows between the one that were displayed on the very top and the very bottom.
I figured it's happening because they are not getting rendered, and therefore not saving the "checked" state in the array.
Then I tried this little piece of code that will scroll through every 5 rows or so, but it still didn't work:
int j = 0;
//loop times is the array.count() over the amount of rows that fit in the screen
while(j < loopTimes){
int n = j*fitToScreen;
Listview.setSelection(n);
j++ ;
}
It just jumps straight to the bottom, without reading those rows.
My guess is that there's not enough time for the rows to render.
Is there any other way of scrolling down without skipping the rows, or accomplishing what that am trying to do?
Thanks in advance.
Is there are way to get a count of the number of visible listview children?
I have a listview with info linked to a database that can change at any time. When the database is changed, I send out a broadcast notifying the ui class handling the list view. The child element relating to the changed data is then updated. I am achieving this by giving each listview item a tag, and then iterating over the listviews to find the row matching the tag from the broadcast.
I want to only iterate over the visible children. There is no need for me to manually update views that are not visible, as they will reflect the new data when they are created. I currently iterate from listView.getfirstVisiblePosition() to listView.getChildCount(). This is better than nothing, as I don't examine rows above the visible rows, but I don't want to examine the rows below them either.
I checked the android developers listView page and didn't find anything. Anyone know of a way I can get the count of visible children?
Thanks!
This is a quick way to get visible children count:
int visibleChildCount = (listView1.getLastVisiblePosition() - listView1.getFirstVisiblePosition()) + 1;
listView.getLastVisiblePosition(), is this what you are looking for? if not,
Iteration through child views...
int count = 0;
for (int i = 0; i <= listView.getLastVisiblePosition(); i++)
{
if (listView.getChildAt(i) != null)
{
count++; // saying that view that counts is the one that is not null,
// because sometimes you have partially visible items....
}
}
In reference to greg7gkb's comment above - just wanted to point out in case anyone is using this that it will make your count off by one. It should be
(listView1.getLastVisiblePosition() - listView1.getFirstVisiblePosition()) + 1
So, if the last visible was 8 and the first visible was 5, you would have (8-5)+1 = 4 showing:5,6,7, and 8.
It looks like A. Abiri got it right below.
How will i go about saving the state of a listview item during scrolling, so that the recycler does not use it when displaying the next row being. i basically have a listview with 4 textviews and one of the textview is displayed based on a condition, derived from a database. For clarity sake, i will call that dependant textview "A".
my problem is that, simplest case: if "A" is being displayed for only the first item or any other row in the list and its not displayed anywhere else, when scrolling, "A" is displayed on other rows that should not have it. i understand the concept of listview reusing rows, but i can't figure out how to save it on an item, so it doesn't get used in another row. Here is a simplified code with just 2 textview:
holder.viewItemName = (TextView)view.findViewById(R.id.nameId);
holder.viewdescriptionStatus = (TextView)view.findViewById(R.id.viewdescriptionId);
int namecolumn = c.getColumnIndex(DBAdapter.NAME);
String name = c.getString(namecolumn);
holder.viewItemName.setText(name);
int description = c.getColumnIndex(DBAdapter.description);
String descriptionstatus = c.getString(description);
/*problem am having here*/
if(description != null){
holder.viewdescriptionStatus.setText("description available");
holder.viewdescriptionStatus.setTextColor(Color.BLUE);
}
as you can see, am using a viewHolder, but i have come to realise that viewHolder doesn't hold the logic as well. i don't know how to save the state of the holder.viewdescriptionStatus based on that condition. Most of the examples i have seen are based on checkboxes. Please anyone with ideas?.. it will be really appreciated.
P.S : i am using bindView() and newView() since i am using an SQLdatabase and SimpleCursorAdapter. i have the same issue with clicking, but i want to solve the scrolling part first. Thank you for your time.
Try this
holder.viewdescriptionStatus.setText(description != null ? "description available" : "");