我有一个列表,通过Handler postDelayed()方法每2秒刷新一次。
运行AsyncTask每2秒发出一个HTTP GET请求,将JSON转换为对象列表,然后设置ListAdapter:
MyListAdapter adapter = new MyListAdapter(someObjects);
setListAdapter(adapter);
我的问题是,每次任务完成(大约每两秒钟),我的列表会跳回到顶部,即使我已向下滚动到列表的中间或底部。这对最终用户来说非常烦人,所以我需要在后台更新列表,就像它正在做的那样,但是列表的当前视图在AsyncTask完成时不会跳回到顶层。
我可以包含所需的更多代码。我对android开发有些新意,所以我不确定什么对其他人有帮助。
其他信息
从hacksteak25获取建议,我能够尝试从适配器中删除所有数据,然后一次将其添加回一个对象。这不是最终解决方案,因为这可能仍然会导致屏幕跳转,但我正在尝试将其用作概念的证据,以便我可以在某些时候合并数据。
我的问题是我调用以下代码:
MyListAdapter adapter = (MyListAdapter)getListAdapter();
adapter.clear();
for(MyObject myObject : myObjects)
{
adapter.add(myObject);
}
在第一次调用“add(myObject)”之后,正在调用MyListAdapter的getView()方法。此时自定义适配器的私有内部ArrayList是空的,因为我在onCreate()中设置了没有myObjects的适配器,或者因为我在适配器上调用了clear(),我不确定。无论哪种方式,这都会导致getView失败,因为ArrayList中没有对象可以从中获取视图。
getView()看起来像这样:
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
LayoutInflater mInflater = getLayoutInflater();
if (convertView == null)
{
convertView = mInflater.inflate(R.layout.myObject, null);
holder = new ViewHolder();
holder.someProperty = (TextView)convertView.findViewById(R.id.someProperty);
holder.someOtherProperty = (TextView)convertView.findViewById(R.id.someOtherProperty);
holder.someOtherOtherProperty = (TextView)convertView.findViewById(R.id.someOtherOtherProperty);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder)convertView.getTag();
}
// Bind the data efficiently with the holder.
holder.someProperty.setText( mObjects.get(position).getSomeProperty());
...
最后一行是导致IndexOutOfBoundsException的那一行。
如何在不导致列表跳转的情况下处理我想要的数据?
答案 0 :(得分:2)
我认为首选的方法是更新适配器本身而不是替换它。也许您可以使用适配器insert()
和remove()
方法编写合并新旧数据的方法。我认为这应该保持你的立场。
添加信息:
我使用以下作为基本结构。也许有帮助。
public class PlaylistAdapter extends ArrayAdapter<Playlist> {
private ArrayList<Playlist> items;
public PlaylistAdapter(Context context, int textViewResourceId, ArrayList<Playlist> items) {
super(context, textViewResourceId, items);
this.items = items;
}
}