2013-10-22 26 views
0

我有從服務器加載交通報告,並將其顯示在一個時間線(如Twitter),該應用被配置成從所述服務器每隔10秒使用此代碼加載數據的應用程序:Android如何動態更新列表視圖?

@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(); 
     } 

問題是,如果我向下滾動列表並閱讀舊帖子,列表將刷新並將其發送到頂部。我想要像ajax那樣下載數據並將其附加到頂端。或者只是告訴我這是X個新的報告和一個顯示它的按鈕。

我該如何做到這一點?

順便說一句我對android編程非常陌生。

在此先感謝。

編輯:多虧了瓦西里Sochinsky我已經添加了以下內容:

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(); 
      } 
     } 

但列表視圖不與新的數據更新,我怎樣才能做到這一點?編輯2:感謝cogentapps給了我一個解決方案,但我仍然不能將它添加到代碼中,我應該在哪裏添加它?

我已經試過,但日食表明很多錯誤:

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(); 
      } 

這是從我的ListViewAdapter的代碼,我應該在哪裏添加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; 
    } 
} 
+0

add listView.getAdapter()。notifyDataSetChanged() –

+0

@VasilySochinsky感謝您的回答,但您能否告訴我該在哪裏或如何做?對不起,打擾了。 –

+0

很奇怪,這是行不通的,你確定服務器返回給你新的數據嗎?把你從服務器收到的一些日誌打印數據,並檢查它。 –

回答

1

看看在這個問題的答案爲如何將項目添加到列表後保持滾動位置的解釋/例如:Retaining position in ListView after calling notifyDataSetChanged

基本上,你記下的位置和滾動的在添加新數據之前,列表中第一個可見項目的偏移量。之後,您將恢復之前的位置並滾動偏移量。

但是,因爲您要在列表頂部添加新項目,所以getFirstVisiblePosition()返回的位置可能會在刷新後引用其他項目。這是在位置0清爽之前該項目現在可能是位置10.爲了解決這個問題,你需要確定由timeline.php返回項目的數量,並把它添加到index,像這樣:

mList.setSelectionFromTop(index + newItemCount, top); 

你通過比較日期字段可能可能確定哪些項目是新的。 (順便說一句,如果timeline.php只返回最近一組項目,如果用戶滾動到一個不再由timeline.php返回的舊項目,則可能會遇到麻煩。設置新數據後,舊的項目將不再存在,所以你將無法滾動到它。

爲了解決這個問題,你可以保留舊ArrayList周圍,只有在doInBackground()新項目添加到它。而在doInBackground()調用notifyDataSetChanged()。這樣,適配器仍然可以訪問較舊的項目。)

+0

感謝您的answer've試過: 保護無效onPostExecute(無效參數){ \t //找到列表視圖中listview_main.xml \t列表視圖=(ListView中)findViewById(R.id.listview); \t //將結果傳遞給ListViewAdapter.java \t adapter = new ListViewAdapter(MainActivity.this,arraylist); \t //將適配器設置爲ListView \t adapter.addAll(); \t listview.notifyDataSetChanged(); \t //關閉進度對話框 \t mProgressDialog.dismiss(); \t} 但是不工作,和日食給了我錯誤 –

+0

好吧,這不是正確的,我要把它添加到主帖子,但我不知道如何將它添加到代碼。 –

+0

這是Eclipse顯示的錯誤:方法addAll()未定義類型ListViewAdapter –