• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Listview updating item issues

Have a listview with custom rows. 1 imageview and several textviews. My arrayAdapter works perfectly populating the list. When I click on an item I start an activity (for result) to view/modify the item. If it was modified I get a reference to each of the views in the item using findViewById(bla) and I update them using setText, setImageResourceID, etc... This works while the view I just updated is in sight. However, when scrolled out of view the Icon on my listview item goes into green spaz-mode. when scrolled back into view.

I should probably mention that I'm sing a holder process to smooth scroll my listview. Not sure if this is the problem or if it's unrelated. Been trying to find articles on how to clear my listview after an edit and reload my existing data using the same source and arrayadapter. Not having any luck finding out how to do this. Any ideas out there? Went from a 10 year windows programmer to android 3 months ago. Finding the transition unsettling so far but determined. Help?
 
This is after updating the item in another activity and returning a result. The code for attempting to update the listview item is in the below onActivityResult text. What I want to do (but can't find help on) is to simply update the original data source and then update the listview item directly. I'm starting to think this isn't possible. As a matter of fact, if I scroll down to a listview item that's below and try to edit it, the proper data is passed on to the activity called, but the item is never updated in the listview at all. Guessing the listview doesn't call the actual item that I edited.

The listview and adapter work perfectly when starting it all up. Scrolling and all are great. It's after I try to update an item that things go south.

To repeat myself.
1. Click on item is listview
2. Edit the data in the activity called (for result)
3. Update my original data used to populate the listview
4. Update what's displayed in the listview to reflect my changes

The third item in the list below is fine until it's scrolled off the screen. Tried this with a holder-arrayAdapter and then with a standard arrayAdapter,
Still stuck on windows listviews so this is rather new to me how the adapters work.
I also have tried notifying the adapter of changes but I've read that that only works if you insert or delete from the original data.

at this point I'd settle for clearing the listview and loading the data again. setting arrayAdapter is suppose to be a bad thing to do, I hear. Lots more open help out there when I was a windows programmer.

issue1.jpg




Java:
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 501 && resultCode == RESULT_OK) {

            DecimalFormat f = new DecimalFormat("000,000");

            int locid = data.getIntExtra("locationid", 1);
            int id = data.getIntExtra("id", -1);
            int pos = data.getIntExtra("position", -1);
            int mil = data.getIntExtra("mileage", 0);
            double cos = data.getDoubleExtra("cost", 0);
            String typ = data.getStringExtra("type");
            String tit = data.getStringExtra("title");
            String des = data.getStringExtra("description");
            String dat = data.getStringExtra("date");

            ImageView icon = (ImageView) v.findViewById(R.id.rowIcon);
            TextView cat = (TextView) v.findViewById(R.id.rowCategory);
            TextView desc = (TextView) v.findViewById(R.id.rowDescription);
            TextView mileage = (TextView) v.findViewById(R.id.rowMileage);
            TextView date = (TextView) v.findViewById(R.id.rowDate);
            TextView cost = (TextView) v.findViewById(R.id.rowCost);
            TextView loc = (TextView) v.findViewById(R.id.rowLocation);

            LocalDateTime lt = convert.DateTimeFromString(dat);

            icon.setImageResource(getIconIndex(typ));
            cat.setText(typ);
            items[ItemPosition].setCategory(typ);

            desc.setText(des);
            items[ItemPosition].setDescription(des);

            date.setText(dat);
            items[ItemPosition].setEntryDate(dat);

            mileage.setText(f.format(mil));
            items[ItemPosition].setMileage(mil);

            date.setText(convert.DateAndTimeValuesAsString(lt));
            items[ItemPosition].setEntryDate(dat);

            loc.setText(String.valueOf(locid));
            items[ItemPosition].setLocationID(1);

            cost.setText(convert.CurrencyAsText(cos));
            items[ItemPosition].setCost(cos);
        }
    }
 
Upvote 0
This is after updating the item in another activity and returning a result. The code for attempting to update the listview item is in the below onActivityResult text. What I want to do (but can't find help on) is to simply update the original data source and then update the listview item directly. I'm starting to think this isn't possible. As a matter of fact, if I scroll down to a listview item that's below and try to edit it, the proper data is passed on to the activity called, but the item is never updated in the listview at all. Guessing the listview doesn't call the actual item that I edited.

The listview and adapter work perfectly when starting it all up. Scrolling and all are great. It's after I try to update an item that things go south.

To repeat myself.
1. Click on item is listview
2. Edit the data in the activity called (for result)
3. Update my original data used to populate the listview
4. Update what's displayed in the listview to reflect my changes

The third item in the list below is fine until it's scrolled off the screen. Tried this with a holder-arrayAdapter and then with a standard arrayAdapter,
Still stuck on windows listviews so this is rather new to me how the adapters work.
I also have tried notifying the adapter of changes but I've read that that only works if you insert or delete from the original data.

at this point I'd settle for clearing the listview and loading the data again. setting arrayAdapter is suppose to be a bad thing to do, I hear. Lots more open help out there when I was a windows programmer.

View attachment 157239



Java:
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 501 && resultCode == RESULT_OK) {

            DecimalFormat f = new DecimalFormat("000,000");

            int locid = data.getIntExtra("locationid", 1);
            int id = data.getIntExtra("id", -1);
            int pos = data.getIntExtra("position", -1);
            int mil = data.getIntExtra("mileage", 0);
            double cos = data.getDoubleExtra("cost", 0);
            String typ = data.getStringExtra("type");
            String tit = data.getStringExtra("title");
            String des = data.getStringExtra("description");
            String dat = data.getStringExtra("date");

            ImageView icon = (ImageView) v.findViewById(R.id.rowIcon);
            TextView cat = (TextView) v.findViewById(R.id.rowCategory);
            TextView desc = (TextView) v.findViewById(R.id.rowDescription);
            TextView mileage = (TextView) v.findViewById(R.id.rowMileage);
            TextView date = (TextView) v.findViewById(R.id.rowDate);
            TextView cost = (TextView) v.findViewById(R.id.rowCost);
            TextView loc = (TextView) v.findViewById(R.id.rowLocation);

            LocalDateTime lt = convert.DateTimeFromString(dat);

            icon.setImageResource(getIconIndex(typ));
            cat.setText(typ);
            items[ItemPosition].setCategory(typ);

            desc.setText(des);
            items[ItemPosition].setDescription(des);

            date.setText(dat);
            items[ItemPosition].setEntryDate(dat);

            mileage.setText(f.format(mil));
            items[ItemPosition].setMileage(mil);

            date.setText(convert.DateAndTimeValuesAsString(lt));
            items[ItemPosition].setEntryDate(dat);

            loc.setText(String.valueOf(locid));
            items[ItemPosition].setLocationID(1);

            cost.setText(convert.CurrencyAsText(cos));
            items[ItemPosition].setCost(cos);
        }
    }
Long time I not use listview, I use recycle view. But they have same behaviour, you have to call adapter.notifyDataSetChanged() after the list modified to make list rerender.
 
Upvote 0
I've solved both issues. Actually found that the String value that I was using to select my icon in my arrayadapter was appearantly getting a string with an extra space in it from the return data. This caused my ImgID variable that I was using to set the image to default to ic_launcher (which I set as default icon for testing). I changed the cat == "VALUE" to a cat.contains("VALUE") to avoid this issue.

Java:
        int imgID = R.drawable.ic_launcher_background;
        String cat = data.getCategory().toUpperCase();
        if (cat.contains ("MAINTENANCE")) {
            imgID = R.drawable.icon_engine;
        } else if (cat.contains ("DOCUMENT")) {
            imgID = R.drawable.icon_docs;
        } else if (cat.contains ("FUEL")) {
            imgID = R.drawable.icon_fuel;
        } else if (cat.contains ("DRIVING")) {
            imgID = R.drawable.icon_steeringwheel;
        } else if (cat.contains ("BUSINESS")) {
            imgID = R.drawable.icon_taxi;
        }

As for updating the Listview Item I stripped most of my code out of the above code and simply created a new itemData using the returned data.

Java:
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 501 && resultCode == RESULT_OK) {

            DecimalFormat f = new DecimalFormat("000,000");

            int locid = data.getIntExtra("locationid", 1);
            int id = data.getIntExtra("id", -1);
            int pos = data.getIntExtra("position", -1);
            int mil = data.getIntExtra("mileage", 0);
            double cos = data.getDoubleExtra("cost", 0);
            String typ = data.getStringExtra("type");
            String tit = data.getStringExtra("title");
            String des = data.getStringExtra("description");
            String dat = data.getStringExtra("date");

            LocalDateTime lt = convert.DateTimeFromString(dat);

            items[ItemPosition] = new itemData(id, des, mil, cos, "", typ, 1, 1, lt);
            mAdapter.notifyDataSetChanged();
        }
    }

My ItemPosition variable stores the value of the item clicked on in the listview onclicklistener so that when a result is returned I can get the actual item that was clicked to edit. mAdapter.notifyDataSetChanged() does update the entire view after the original data has been modified. My issues were self-inflicted with the string comparison and not properly updating the original data. Live and learn, right?
 
Upvote 0
I've solved both issues. Actually found that the String value that I was using to select my icon in my arrayadapter was appearantly getting a string with an extra space in it from the return data. This caused my ImgID variable that I was using to set the image to default to ic_launcher (which I set as default icon for testing). I changed the cat == "VALUE" to a cat.contains("VALUE") to avoid this issue.

Java:
        int imgID = R.drawable.ic_launcher_background;
        String cat = data.getCategory().toUpperCase();
        if (cat.contains ("MAINTENANCE")) {
            imgID = R.drawable.icon_engine;
        } else if (cat.contains ("DOCUMENT")) {
            imgID = R.drawable.icon_docs;
        } else if (cat.contains ("FUEL")) {
            imgID = R.drawable.icon_fuel;
        } else if (cat.contains ("DRIVING")) {
            imgID = R.drawable.icon_steeringwheel;
        } else if (cat.contains ("BUSINESS")) {
            imgID = R.drawable.icon_taxi;
        }

As for updating the Listview Item I stripped most of my code out of the above code and simply created a new itemData using the returned data.

Java:
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 501 && resultCode == RESULT_OK) {

            DecimalFormat f = new DecimalFormat("000,000");

            int locid = data.getIntExtra("locationid", 1);
            int id = data.getIntExtra("id", -1);
            int pos = data.getIntExtra("position", -1);
            int mil = data.getIntExtra("mileage", 0);
            double cos = data.getDoubleExtra("cost", 0);
            String typ = data.getStringExtra("type");
            String tit = data.getStringExtra("title");
            String des = data.getStringExtra("description");
            String dat = data.getStringExtra("date");

            LocalDateTime lt = convert.DateTimeFromString(dat);

            items[ItemPosition] = new itemData(id, des, mil, cos, "", typ, 1, 1, lt);
            mAdapter.notifyDataSetChanged();
        }
    }

My ItemPosition variable stores the value of the item clicked on in the listview onclicklistener so that when a result is returned I can get the actual item that was clicked to edit. mAdapter.notifyDataSetChanged() does update the entire view after the original data has been modified. My issues were self-inflicted with the string comparison and not properly updating the original data. Live and learn, right?
You should compare String using stringA.equals(stringB) instead of use stringA.contains(stringB).
At the time I begin learn Android, I got very much issues too.
 
Upvote 0

BEST TECH IN 2023

We've been tracking upcoming products and ranking the best tech since 2007. Thanks for trusting our opinion: we get rewarded through affiliate links that earn us a commission and we invite you to learn more about us.

Smartphones