0

I have an app that loads the traffic report from a server and shows it in a timeline (like twitter), the app is configured to load the data from the server every 10 seconds using this code:

 @Override
        public void onResume() {
          super.onResume();
          autoUpdate = new Timer();
          autoUpdate.schedule(new TimerTask() {
             @Override
             public void run() {
               runOnUiThread(new Runnable() {
                 public void run() {
                   new DownloadJSON2().execute(); // this is the class that downloads the data from the server.
                 }
               });
             }
           }, 0, 10000); // updates each 10 secs
         }


        @Override
        public void onPause() {
           autoUpdate.cancel();
           super.onPause();
        }

The problem is that if I scroll down the list and I'm reading the older posts, the list refreshes and send me to the top of it. I want to download that data like ajax and append it to the top. Or just to tell me that is X new reports and a button to show it.

How can I acomplish this?

BTW I'm extremely new to android programming.

Thanks in advance.

EDIT: Thanks to Vasily Sochinsky i've added the following:

public class DownloadJSON extends AsyncTask<Void, Void, Void> {

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                // Create a progressdialog
                mProgressDialog = new ProgressDialog(MainActivity.this);
                // Set progressdialog title
                mProgressDialog.setTitle("Cargando reportes en tiempo real");
                // Set progressdialog message
                mProgressDialog.setMessage("Por favor espere");
                mProgressDialog.setIndeterminate(false);
                // Show progressdialog
                mProgressDialog.show();
            }

            @Override
            protected Void doInBackground(Void... params) {
                // Create an array
                arraylist = new ArrayList<HashMap<String, String>>();
                // Retrieve JSON Objects from the given URL address
                jsonobject = JSONfunctions
                        .getJSONfromURL("http://server.com/timeline.php");

                try {
                    // Locate the array name in JSON
                    jsonarray = jsonobject.getJSONArray("datos");

                    for (int i = 0; i < jsonarray.length(); i++) {
                        HashMap<String, String> map = new HashMap<String, String>();
                        jsonobject  = jsonarray.getJSONObject(i);
                        // Retrive JSON Objects
                       // jsonobject1  = jsonobject.getJSONObject("contenido");
                        map.put("imagen", jsonobject.getString("imagen"));
                        map.put("quien", jsonobject.getString("quien"));
                        map.put("fecha", jsonobject.getString("fecha"));
                        map.put("reporte", jsonobject.getString("reporte"));
                      //  map.put("imgs", jsonobject1.getString("imgs"));
                      //  map.put("video", jsonobject1.getString("video"));
                        // Set the JSON Objects into the array
                        arraylist.add(map);
                    }
                } catch (JSONException e) {
                    Log.e("Error", e.getMessage());
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void args) {
                // Locate the listview in listview_main.xml
                listview = (ListView) findViewById(R.id.listview);
                // Pass the results into ListViewAdapter.java
                adapter = new ListViewAdapter(MainActivity.this, arraylist);
                // Set the adapter to the ListView
                listview.setAdapter(adapter);
                adapter.notifyDataSetChanged();
                // Close the progressdialog
                mProgressDialog.dismiss();
            }
        }

But the listview is not updating with the new data, how can i achieve this?

EDIT 2: Thanks to cogentapps that gave me a solution, but i still can not add it to the code, where should i add it?

I've tried this but eclipse shows many errors:

protected void onPostExecute(Void args) {
                // Locate the listview in listview_main.xml
                listview = (ListView) findViewById(R.id.listview);
                // Pass the results into ListViewAdapter.java
                adapter = new ListViewAdapter(MainActivity.this, arraylist);
                // Set the adapter to the ListView
                adapter.addAll();
                listview.notifyDataSetChanged();
                // Close the progressdialog
                mProgressDialog.dismiss();
            }

This is the code from my ListViewAdapter, where should i add the adapter.add()?

public class ListViewAdapter extends BaseAdapter {

    // Declare Variables
    Context context;
    LayoutInflater inflater;
    ArrayList<HashMap<String, String>> data;
    ImageLoader imageLoader;
    HashMap<String, String> resultp = new HashMap<String, String>();
    String coment;
    public String img;
    public int imga;
    public ListViewAdapter(Context context,
            ArrayList<HashMap<String, String>> arraylist) {
        this.context = context;
        data = arraylist;
        imageLoader = new ImageLoader(context);
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {
        // Declare Variables
        TextView quien;
        ImageView imagen;
        TextView reporte;
        TextView fecha;

        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View itemView = inflater.inflate(R.layout.listview_item, parent, false);
        // Get the position
        resultp = data.get(position);

        // Locate the TextViews in listview_item.xml
        // Locate the ImageView in listview_item.xml
        imagen = (ImageView) itemView.findViewById(R.id.imagen);
        fecha = (TextView) itemView.findViewById(R.id.fecha);
        quien = (TextView) itemView.findViewById(R.id.quien);
        reporte = (TextView) itemView.findViewById(R.id.reporte);
        // Capture position and set results to the TextViews
     // Capture position and set results to the ImageView
        // Passes flag images URL into ImageLoader.class
        imageLoader.DisplayImage(resultp.get(MainActivity.IMAGEN), imagen);
        fecha.setText(resultp.get(MainActivity.FECHA));
        reporte.setText(resultp.get(MainActivity.REPORTE));
        quien.setText(resultp.get(MainActivity.QUIEN));
        // Capture ListView item click
        /*
        itemView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // Get the position
                resultp = data.get(position);
                    Intent intent = new Intent(context, SingleItemView.class);
                    // Pass all data rank

                    intent.putExtra("imagen", resultp.get(MainActivity.IMAGEN));

                    intent.putExtra("quien", resultp.get(MainActivity.QUIEN));

                    intent.putExtra("fecha", resultp.get(MainActivity.FECHA));
                    // Start SingleItemView Class
                    context.startActivity(intent);


            }
        });
        */
        return itemView;
    }
}
Douglas Roos
  • 533
  • 8
  • 26

1 Answers1

1

Take a look at the answer to this question for an explanation / example of how to maintain scroll position after adding items to a list: Retaining position in ListView after calling notifyDataSetChanged

Basically, you make a note of the position and scroll offset of the first visible item in the list before adding new data. Then afterwards, you restore the previous position and scroll offset.

However, because you're adding new items at the top of the list, the position returned by getFirstVisiblePosition() may refer to a different item after refreshing. The item that was at position 0 before refreshing may now be position 10. To fix that, you need to determine the number of new items returned by timeline.php and add it to index, like this:

mList.setSelectionFromTop(index + newItemCount, top);

You could probably determine which items are new by comparing the date field.

(By the way, if timeline.php only returns the most recent set of items, you could run into trouble if the user has scrolled to an older item which is no longer returned by timeline.php. After setting the new data, the old item will no longer be present, so you won't be able to scroll to it.

To fix that, you could keep the old ArrayList around and only add new items to it in doInBackground(). And call notifyDataSetChanged() in doInBackground(). That way, the adapter will still have access to older items.)

Community
  • 1
  • 1
cnnr
  • 1,606
  • 14
  • 16
  • Thanks for the answer've tried: protected void onPostExecute(Void args) { // Locate the listview in listview_main.xml listview = (ListView) findViewById(R.id.listview); // Pass the results into ListViewAdapter.java adapter = new ListViewAdapter(MainActivity.this, arraylist); // Set the adapter to the ListView adapter.addAll(); listview.notifyDataSetChanged(); // Close the progressdialog mProgressDialog.dismiss(); } But is not working, and eclipse gaves me errors – Douglas Roos Oct 23 '13 at 00:25
  • Ok, that's not showing right, i'm gonna add it to the main post, but i don't know how to add it to the code. – Douglas Roos Oct 23 '13 at 00:27
  • This is the error showed by Eclipse: The method addAll() is undefined for the type ListViewAdapter – Douglas Roos Oct 23 '13 at 00:39
  • thanks for the help, can you please explain me a little better? – Douglas Roos Oct 23 '13 at 23:02
  • Sorry for the delay. I edited my answer to address your problem better. – cnnr Oct 26 '13 at 21:41
  • Thanks! Finally the listview is keeping the scroll, but i'm still unable to put the notifyDataSetChanged(), don't know where to put it. I want the list to refresh like using ajax, but don't know the best way to do it. I'm very new to Android and Java Programming (POO). – Douglas Roos Oct 28 '13 at 02:35