我有一个应用程序从服务器加载流量报告并在时间轴(如twitter)中显示,应用程序配置为使用此代码每10秒从服务器加载数据:
@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个新报告和一个显示它的按钮。
我怎样才能完成这个?
BTW我对android编程非常陌生。
提前致谢。
编辑:感谢Vasily 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();
}
}
但是listview没有使用新数据进行更新,我该如何实现?
编辑2:感谢cogentapps给了我一个解决方案,但我仍然无法将其添加到代码中,我应该在哪里添加它?
我试过这个但是eclipse显示了很多错误:
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 :(得分:1)
查看此问题的答案,了解在将项目添加到列表后如何保持滚动位置的说明/示例:Retaining position in ListView after calling notifyDataSetChanged
基本上,在添加新数据之前,请记下列表中第一个可见项目的位置和滚动偏移。然后,您将恢复先前的位置并滚动偏移。
但是,由于您要在列表顶部添加新项目,因此getFirstVisiblePosition()
返回的位置可能会在刷新后引用其他项目。刷新前位置0的项目现在可能是位置10.要解决此问题,您需要确定timeline.php
返回的新项目的数量,并将其添加到{{1} },像这样:
index
您可以通过比较日期字段来确定哪些项目是新的。
(顺便说一下,如果mList.setSelectionFromTop(index + newItemCount, top);
只返回最新的一组项目,如果用户滚动到timeline.php
不再返回的旧项目,则可能会遇到麻烦。设置新数据时,旧项目将不再存在,因此您将无法滚动到该项目。
要解决此问题,您可以保留旧timeline.php
,并仅在ArrayList
中向其添加新项目。并在doInBackground()
中致电notifyDataSetChanged()
。这样,适配器仍然可以访问旧项目。)