In my app I have a ListView
that contains times of different timezones. With a seekbar
the 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?
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);
}