How to update non-bound child view for ALL items in a ListView? - android

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.

Related

Change ImageView background in a Row of ListView

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"

Listview Row incrementing with new value

I have a listview with radio buttons now i need to add one value from a edittext after typing some thing in the edittext the typed text should appear in the listview as next row.? how it is posible.?
ListView with simpleArrayAdapter :
Follow these steps it may help:
1. Fetch the value from edit text after the user types using gettext()
2. Insert this value in an array.
3. create a list view.
4. create an arrayAdapter with the already created array as source.
5. Now set the adapter with listview using (array variable).setAdapter(adapter name);
For every time the user updates use notifyDataSetChanged() to refresh your listview with the new contents.
Pseudo code:
onClick(){
array.add(editText.gettext());
adapter.notifyDataSetChanged();
}
Click here for more.

onListItemClick, can I get the absolute position from 'id'?

I have
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, column));
getListView().setTextFilterEnabled(true);
and
public void onListItemClick(
ListView parent, View v, int position, long id)
I need to fine the position in column of the clicked item. Position is no good since the filter is on. Can I somehow derive the real position from 'id'?
One possible solution:
After you've set up a listview, do a once-through of the entire list, adding all the visible items indexes to an array. For instance, in a 5 element list, with the 2nd and 4th items not visible, it would look like this:
indexes[0] = 0
indexes[1] = -1
indexes[2] = 1
indexes[3] = -1
indexes[4] = 2
then when you get a position in the onListItemClick, that's just an index in the "indexes" array that returns the real position in the filtered ListView.
Then inside your onListItemClick, just use the position passed as a parameter as a key to look up the position in the filtered list.
EDIT: SparseArray is overkill. Offering reasonably easy solution.
I guess you can use .getChildCount() and .getChildAt() and then check .getVisibility() == View.VISIBLE on each to count the number of visible, and check if the clicked item is equal to the current iterrated. There's no straightforward way I'm afraid.
position in listview is the position of the element in generic object ie list you pass to an array adapter.
I haven't ever had good luck with ItemIDs.
Might want to instead pull the data from View v. This view might contain a TextView, which you could use to determine which row the user clicked on. This won't work if multiple rows can be displayed identically though...
So if that is the case, you are going to have to iterate through the dataset calling getItemID(int position) on every element in the adapter. Store these longs in an array the same size as the dataset, and use the same index on both your column dataset and this long ItemID array.

Android - OnClick handler for dynamic ListView data?

I have a ListView that is filled with a dynamic set of data each time the Activity is created. For simplicity's sake, lets say each ListView item is a employee's name. Under the hood, each employee has an employee_id number. This number is not visible anywhere in the interface.
When I click on an employee's name in the ListView, I want to launch another activity, passing the corresponding employee's employee_id to that Activity.
I understand how to implement the onClick handler for the ListView. My question is, where would I store and retrieve the employee_id for each employee? Would I simply store it in a hash/map along with the position in the list that the employee shows up at? And when I click, I just determine the position in the list I clicked at, and then get the employee_id from the hash using that position?
Use the ArrayAdapter with a list Employees - assuming you have Employee-object.
public class MyActivity extends ListActivity {
// list of employees
private List<Employee> employees = new ArrayList<Employee>();
Then use the position parameter in OnItemClick to get the employee-object.
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int employee_id = ((Employee) getListAdapter().getItem(position)).getId();
// ...
}
You can also extend the ArrayAdapter to tailor the list for employee-objects:
How to use ArrayAdapter<myClass>
You use an Adapter based on some set of data (for example, a List of Employee objects). When you set an onItemClickListener on your ListView, the onItemClick method gets an int parameter that is the position in the underlying data. Use that to pluck the Employee object out of your List, and there's the employee id.
I would suggest doing what you stated above. Or, I don't really think it's nice solution, I also think there aint any, but you could add a label with no content (maxHeight and maxWdith are both 0, or invisible? never tried that) and set the text. I don't know how it is resource wise. But you won't have to save the list anymore, which saves some memory if you have a big list.

How to save the state of an item in a listview android

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" : "");

Categories

Resources