Search code examples
androidlistviewlistadapter

Update ListView without data beiing changed


In my app I have a ListView that contains times of different timezones. With a seekbarthe user can change the current time of a timezone and the other zones are supposed to update their times as well.

In my onCreate() method I iniciate the ListView and set a Time variable to the current time of my previously selected location. In addition I set aOnSeekBarChangeListener to my seekbar.

private ArrayList<Welt> welts;
private SimpleArrayAdapter arrayAdapter;

public void onCreate(Bundle savedInstanceState) {

    ...

    arrayAdapter = new SimpleArrayAdapter(this, R.layout.listwelt, welts);
    showwelt();

    ...

    now.setToNow();
    now.set(now.toMillis(false));
    pos = extras.getInt("weltcompare");
    now.switchTimezone(welts.get(pos).zone);

    ...

    seek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            offset = seekBar.getProgress()*5 - start;
            arrayAdapter.notifyDataSetChanged();
            //showwelt();
        }

        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        public void onStopTrackingTouch(SeekBar seekBar) {
            offset = seekBar.getProgress()*5 - start;
            arrayAdapter.notifyDataSetChanged();
            //showwelt();
        }

    });

    ...

}

public void showwelt() {
    ListView listTest = (ListView)findViewById(R.id.mylistwelt);
    listTest.setAdapter(arrayAdapter);
    listTest.setDivider(null);
    listTest.setDividerHeight(0);
}

At last my ArrayAdapter class:

public class SimpleArrayAdapter extends ArrayAdapter<Welt> {
    private final int resource;

    public SimpleArrayAdapter(Context context, int resource, ArrayList<Welt> arrays) {
        super(context, resource, arrays);
        this.resource = resource;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        Welt cobject = getItem(position);
        RelativeLayout listView;

        if(convertView==null) {
            listView = new RelativeLayout(getContext());
            String inflater = Context.LAYOUT_INFLATER_SERVICE;
            LayoutInflater vi;
            vi = (LayoutInflater)getContext().getSystemService(inflater);
            vi.inflate(resource, listView, true);
        }else{
            listView = (RelativeLayout) convertView;
        }

        TextView tv1 = (TextView)listView.findViewById(R.id.listwelt1);
        tv1.setText(cobject.ort);
        TextView tv2 = (TextView)listView.findViewById(R.id.listwelt2);
        tv2.setText(cobject.land);
        TextView tv3 = (TextView)listView.findViewById(R.id.listwelt3);
        now.set(base);
        now.minute = now.minute + offset;
        now.normalize(false);
        now.set(now.toMillis(false));
        now.switchTimezone(cobject.zone);
        tv3.setText(TimeMateActivity.formatDateTime(0, 0, 0, now.hour, now.minute));
        TextView tv4 = (TextView)listView.findViewById(R.id.listwelt4);
        tv4.setText(TimeMateActivity.formatDateTime(now.monthDay, now.month, now.year, 24, 0));

        if(position == pos) {
            tv1.setTypeface(null, Typeface.BOLD);
            tv2.setTypeface(null, Typeface.BOLD);
            tv3.setTypeface(null, Typeface.BOLD);
        }

        return listView;
    }
}

So the only data that is changed while the activity is running is the variable offset. I think that's the reason why arrayAdapter.notifyDataSetChanged() doesn't work, while calling showwelt() in the OnSeekBarChangeListener does the job, but resets the ListView to the top.

I read a couple of posts, but none of them helped. I tried to clear the adapter and add all items again before calling notifyDataSetChanged(). I tried saving the current scroll position of the list and restore it.

How should I solve my problem?


Solution

  • I found a solution:

    My OnSeekBarChangeListener methods now look like this.

    OnProgressChanged: here I calculate the value for my offset variable and call the showwelt() function

    OnStartTrackingTouch: here I save the current scroll position of the listview

    OnStopTrackingTouch: empty

    And my showwelt function looks like this:

    public void showwelt() {
        ListView listTest = (ListView)findViewById(R.id.mylistwelt);
        SimpleArrayAdapter arrayAdapter = new SimpleArrayAdapter(this, R.layout.listwelt, welts);
        listTest.setAdapter(arrayAdapter);
        listTest.setDivider(null);
        listTest.setDividerHeight(0);
        listTest.setSelectionFromTop(index, top);
    }