user1801060
user1801060

Reputation: 2821

Refreshing ListView data after setting Preferences double populates

I'm a Java and Android newbie. I'm creating something that requires a listview. The listview data is calculated from GPS coordinates which are set in a preferences window. My problem is that after I enter in new coordinates, the listview data does'nt reflect this.

What have I tried so far? I've watched the Google I/O 2010 video and am using notifyDataSetChanged() during onResume().

However when I do this, the listview and its header are populated two times. What am I doing wrong? Sections of the code follow

public class MainActivity extends Activity{
GPSTracker gps;
Date yetzt = new Date();    
String locationName = "";
double latitude = 0;
double longitude = 0;
double elevation = 0;

List<RowItem> rowItems;
ListView listView;
String tmp = "";
ItemListViewAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    rowItems = new ArrayList<RowItem>();

    // check if GPS enabled
    if (gps.canGetLocation()) {
        showInfo();
    } else {
        // can't get location
        // GPS or Network is not enabled
        // Ask user to enable GPS/network in settings
        gps.showSettingsAlert();
    }
}

private void showInfo() {       
    SharedPreferences sharedPrefs = PreferenceManager
            .getDefaultSharedPreferences(this);

    TimeZone tz = TimeZone.getDefault();        
    locationName = tz.getDisplayName(false, TimeZone.SHORT);
    latitude = Float.parseFloat(sharedPrefs.getString("manual_fetch_lat", Double.toString(gps.getLatitude())));
    longitude = Float.parseFloat(sharedPrefs.getString("manual_fetch_long", Double.toString(gps.getLongitude())));      
    TimeZone timeZone = TimeZone.getTimeZone(tz.getID());       

    listView = (ListView) findViewById(R.id.list);
    //add stuff into rowItems here
    adapter = new ItemListViewAdapter(MainActivity.this, R.layout.listview_item_row, rowItems);

    View header = (View)getLayoutInflater().inflate(R.layout.listview_header_row, null);

    TextView t = new TextView(this);
    t = (TextView)header.findViewById(R.id.textView1);
    if ( t != null ) {
        t.setText("Demo");
    }

    listView.addHeaderView(header);
    listView.setAdapter(adapter);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    menu.add(Menu.NONE, 0, 0, R.string.preference_menu_title);
    return super.onCreateOptionsMenu(menu);
}

@Override
protected void onResume() {
    super.onResume();
    adapter.notifyDataSetChanged();
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case 0:
        startActivity(new Intent(this, EditSettingsActivity.class));
        return true;
    }
    return false;
}

}

My ListViewAdapter is as follows

public class ItemListViewAdapter extends ArrayAdapter<RowItem> {
private Context context;

public ItemListViewAdapter(Context context, int resource,
        List<RowItem> objects) {
    super(context, resource, objects);
    this.context = context;
}

/* private view holder class */
private class ViewHolder {
    ImageView imageView;
    TextView txtTitle;
}

public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    RowItem rowItem = getItem(position);

    LayoutInflater mInflater = (LayoutInflater) context
            .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.listview_item_row, null);
        holder = new ViewHolder();
        holder.txtTitle = (TextView) convertView.findViewById(R.id.title);
        holder.imageView = (ImageView) convertView.findViewById(R.id.icon);
        convertView.setTag(holder);
    } else
        holder = (ViewHolder) convertView.getTag();

    holder.txtTitle.setText(rowItem.getTitle());
    holder.imageView.setImageResource(rowItem.getImageId());

    return convertView;
}

}

ListView data is populated as shown

        GeoLocation location = new GeoLocation(locationName, latitude, longitude, elevation, timeZone);
    ComplexZmanimCalendar czc = new ComplexZmanimCalendar(location);
    ComplexZmanimCalendar czcPrevious = new ComplexZmanimCalendar(location);
    ComplexZmanimCalendar czcNight = new ComplexZmanimCalendar(location);
    Calendar cal = Calendar.getInstance();      

    Toast.makeText(getApplicationContext(), "Section 1", Toast.LENGTH_LONG).show();
    //subtract one day from current date
    cal.add(Calendar.DATE, -1);
    czcPrevious.setCalendar(cal);
    diff = czcPrevious.getSunset().getTime() - czcPrevious.getSunrise().getTime();
    interval = diff/12;

    SimpleDateFormat parserSDF=new SimpleDateFormat("HH:mm");   
    List<String> x = new ArrayList<String>();

    for(int counter=0; counter < 12; counter++){    


        tmp = "From "+ parserSDF.format(new Date(czcPrevious.getSunrise().getTime() + (counter*interval) ))+" to "+parserSDF.format(new Date(czcPrevious.getSunrise().getTime() + ((counter+1)*interval) ));
        n = getResources().getIdentifier(logo[counter].toLowerCase(),"drawable", getPackageName());
        item = new RowItem(n, tmp);
        rowItems.add(item);                 
    }       

    diff = czc.getSunrise().getTime() - czcPrevious.getSunset().getTime();
    interval = diff/12;

    for(int counter=0; counter < 12; counter++){                

        tmp = "From "+ parserSDF.format(new Date(czcPrevious.getSunset().getTime() + (counter*interval) ))+" to "+parserSDF.format(new Date(czcPrevious.getSunset().getTime() + ((counter+1)*interval) ));
        n = getResources().getIdentifier(logo[counter].toLowerCase(),"drawable", getPackageName());
        item = new RowItem(n, tmp);
        rowItems.add(item);             

    }

Upvotes: 0

Views: 204

Answers (1)

jpardogo
jpardogo

Reputation: 5666

I dont see any place where you modify or populate your array "rowItems" with any values.

Can you post the EditSettingsActivity so we can see what you do in there?

So far you can change this lines of code:

TextView t = new TextView(this);
t = (TextView)header.findViewById(R.id.textView1);

...for this one...

TextView t = (TextView)header.findViewById(R.id.textView1);

I have just seen your adapter and is almost perfect, I can see you follow the google video of google I/O , XD.... just make your adapter...

static class ViewHolder {

EditSettingsActivity would help to understand the life cycle of your app...but for now...

If your MainActivity depends of some values that you set on EditSettingsActivity, then you have to return the values to the MainActivity to modify the array rowItems declared on MainActivity and after you modify this array then you can call notifyDataSetChanged().

You could do this with startActivityForResult and you can find here how it works:

aryo.info/blog/android-returning-value-to-the-calling.html

I dont know what type of values you are modifying on EditSettingsActivity but you also have the possibility to store them on SharePreferences and retrieve them on your MainActivity when you come back. This way the next time the user access to the app, he keeps the same preferences that he set the last time and only if you uninstall the app they will be removed.

How to use shared preferences:

http://developer.android.com/guide/topics/data/data-storage.html#pref

I have just added and example project in this link that does exactly what you want and it is working:

https://dl.dropboxusercontent.com/u/33565803/StackOverFlowExamples/ListViewHeaderAddItemsNotifyDataExample.zip

Upvotes: 1

Related Questions