我正在研究TCP套接字,我每秒收到一些数据,需要在 ListView 中显示它,因为我使用的是动态listView和自定义数组适配器
我的问题是,当我从TCP套接字收到一组新数据时,一个新对象正在为listItem(findViewById)创建,因为当我滚动我的listview时,它再次在我更新我的时候移到顶部的ListView。
当我只考虑一组数据时,我没有发现上述问题。
我的代码:
doAsynchronousTask = new TimerTask() {
@Override
public void run() {
finalizer = new Runnable() {
public void run() {
try {
new RetriveStock().execute(); // AsyncTask Executes for every 1 sec.
} catch (Exception e) {
// TODO: handle exception
}
}
}
};
handler.post(finalizer);
}
};
timer.schedule(doAsynchronousTask, 0, 1000); // execute in every 1000
// AsyncTask
public class RetriveStock extends AsyncTask<Void, Void, ArrayList<User>> {
@Override
protected ArrayList<User> doInBackground(Void... params) {
message += client.clientReceive(1); // Receive data from socket and put into message (string global variable).
printJson(); // Here I receive data from JSON and put into object
adb = new RSSListAdaptor(DefaultMarketWatch.this,
R.layout.rssitemview, list); // "list" is a global listAdapter.
return null;
}
@Override
protected void onCancelled() {
super.onCancelled();
}
protected void onPostExecute(ArrayList<User> result) {
lv.setAdapter(adb);
adb.notifyDataSetChanged();
super.onPostExecute(result);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
// printJson()
public void printJson() {
String str = "";
/* SOME CODE HERE
FORMATING "message" (STRING VARIABLE) TO A PERFECT JSONARRAY FORMATE, AND PUT INTO VARIABLE "str" */
str = "[" + str + "]";
try {
JSONArray jsonArray = new JSONArray(str);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json = jsonArray.getJSONObject(i);
User obj = new User();
// MY CODE, EITHER ADDING NEW OBJECT OR UPDATING THE EXISTING USER OBJECT.
list.add(obj);
} catch (JSONException e1) {
e1.printStackTrace();
}
}
//我的自定义ArrayAdapter。
public class RSSListAdaptor extends ArrayAdapter<User> {
private List<User> objects = null;
public RSSListAdaptor(Context context, int textviewid,
List<User> objects) {
super(context, textviewid, objects);
this.objects = objects;
}
@Override
public int getCount() {
return ((null != objects) ? objects.size() : 0);
}
@Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView,
ViewGroup parent) {
View view = convertView;
if (null == view) {
LayoutInflater vi = (LayoutInflater) DefaultMarketWatch.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.rssitemview, null);
}
try {
User u = objects.get(position);
if (null != u) {
TextView title_list = (TextView) view.findViewById(R.id.symbol);
TextView ltp_list = (TextView) view.findViewById(R.id.ltp);
TextView high_list = (TextView) view.findViewById(R.id.high);
TextView low_list = (TextView) view.findViewById(R.id.low);
TextView persend_list = (TextView) view.findViewById(R.id.persent);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) title_list
.getLayoutParams();
params.setMargins(0, 0, 25, 0);
title_list.setText("TITLE");
ltp_list.setText("LTP");
high_list.setText("HIGH");
low_list.setText("LOW");
persend_list.setText("PERSENTAGE");
}
} catch (IllegalStateException is) {
is.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return view;
}
}
答案 0 :(得分:1)
请勿在{{1}}中重新创建适配器,并且不要在doInBackground
而是在构造函数中创建一个空适配器或在某个合理的位置创建一个空适配器,当数据进入时,将该数据附加到适配器然后调用onPostExecute
答案 1 :(得分:1)
试试这个:
// save index and top position
int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
// update listview with new data
// restore
mList.setSelectionFromTop(index, top);
或
// Save ListView state
Parcelable state = listView.onSaveInstanceState();
// Set new items
listView.setAdapter(adapter);
// Restore previous state (including selected item index and scroll position)
listView.onRestoreInstanceState(state);