0

I have a ListView in an Android Activity and a custom adapter for that listview. I want to be able to edit a row item and update that row instantly. This works, the modifications of the row is seen But, on scroll i loose all data. This is my Asynk task from where i get the data and update the list row item:

/**
 * 
 */
public class EditNewsFeedPostAsyncTask extends AsyncTask<Void, Void, Boolean> {


    public Activity context;
    public String content;
    public int rowPosition;
    public ListView listView;
    public TextView decriptionTxt;


    @Override
    protected Boolean doInBackground(Void... params) {

        try {
            token = Utils.getToken(context);

            if (token != null) {
                ....
                // {"status":"true"}
                if (result != null) {
                    ....
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return true;
    }

    @Override
    protected void onPostExecute(final Boolean success) {
        if (success) {
            updateListView(rowPosition, content);
        }
    }

    public boolean updateListView(int position, String content) {
        int first = listView.getFirstVisiblePosition();
        int last = listView.getLastVisiblePosition();
        if (position < first || position > last) {
            return false;
        } else {
            View convertView = listView.getChildAt(position - first);
            decriptionTxt.setText(content);
            listView.invalidateViews();
            return true;
        }
    }

    private void updateView(int index, TextView decriptionTxt) {
        View v = listView.getChildAt(index - listView.getFirstVisiblePosition());

        if (v == null)
            return;

        decriptionTxt.setText(content);
        listView.invalidateViews();
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected void onCancelled() {
    }
}

What am i missing? shouldn't the data be persistent? Thx

Gabriela Radu
  • 757
  • 2
  • 12
  • 33

3 Answers3

1

after scrolling, the getView method inside your list's adapter will call and you will return the default view for that.

if you want to change that item permanent, you should update your data set and call notifyDataSetChanged on your adapter.

Mohammad Rahchamani
  • 5,002
  • 1
  • 26
  • 36
1

Make sure you're updating the data, not just the view.

When you modify the row, are you changing the underlying data or just the view? If just the view...

You're probably running into ListView recycling issues. This answer has a great explanation. Basically, ListViews are about efficiency in displaying views based on data, but are not good for holding new data on screen. Every time a ListView item is scrolled out of view, its View is recycled to be used for the item that just scrolled into view. Therefore, if you put "hi" in an EditText and then scroll it off screen, you can say goodbye to that string.

I solved this in my app by ditching ListView altogether and using an array of LinearLayouts (probably a clunky approach, but I had a known list size and it works great now). If you want to continue using a ListView, you'll have to approach it from a "data first" perspective. Like I said, ListViews are great at showing info from underlying data. If you put "hi" in an EditText and simultaneously put that string in the underlying data, it would be there regardless of any scrolling you do. Updating onTextChanged might be cumbersome, so you could also let each row open a dialog in which the user enters their data which then updates the underlying dataset when the dialog closes.

These are just some ideas, based on some assumptions, but editing views in a ListView is, in general, not very in line with how ListViews work.

Community
  • 1
  • 1
NSouth
  • 5,067
  • 7
  • 48
  • 83
1

You must update the object in your listView adapter, not only the views!

Rami
  • 7,879
  • 12
  • 36
  • 66