我已经阅读了很多有关如何更新ListView的问题。他们几乎都说出adapter.notifyDataSetChanged()(如果在带有runOnUiThread的单独线程中)。
我的问题开始得更早:我什至如何获得所需的适配器,或者为此,一个Activity调用runOnUiThread?
这是我当前代码的非常简化的版本:
我有一个数据类,可以随时随地更新。update方法需要启动一个新的Thread,这就是为什么我不能简单地等待返回值的原因。
class Data {
private static double[] data = new double[7]
public static void update(final Context context) {
new Thread(new Runnable() {
@Override
public void run() {
//do lots of complicated stuff
}
}).start();
}
public double[] getData {
return data;
}
我有一个Activity(不是主要的Activity),其中包含ListView
public class ListViewActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ListView);
ListView listView = (ListView) findViewById(R.id.MyListView);
listView.setAdapter(new CustomListViewAdapter(this));
}
然后,我使用自定义适配器以所需的方式设置ListView。
class CustomListViewAdapter extends BaseAdapter {
private final LayoutInflater layoutInflater;
public CustomListViewAdapter(Context context) {
layoutInflater = LayoutInflater.from(context);
}
@Override
public View getView(int position, View view, ViewGroup parent) {
ViewHolder viewHolder = new ViewHolder();
if (view == null) {
view = layoutInflater.inflate(R.layout.listView_row_layout, parent, false);
viewHolder.value = (TextView) view.findViewById(R.id.listViewDataTextField);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
double data = Data.getData()[position];
viewHolder.value.setText(data+"");
return view;
}
private class ViewHolder {
TextView value;
}
现在,我想在update()方法中的线程完成获取新数据后立即使用ListView更新。获取数据可能需要花费几秒钟的时间,因此无法预测到那时将激活哪些活动。如果我的ListViewActivity是活动的,我希望ListView立即更改为新数据。
那么,如何在另一个线程中从另一个类(不是Activity)更新该ListView?我不认为将适配器放在静态字段中是个好主意,因为ListViewActivity可能一直被创建和销毁?但是我还有什么其他选择?
extendIt似乎可以将您的主要问题简短地表述为“我什至如何获得适配器”,因此,我将尝试解决该问题。让我们尝试使用旧的Java单例来解决该问题。这个想法是为您需要更新的所有视图创建全局配置并预创建适配器:
public class GlobalConfig {
private static GlobalConfig config = null;
private CustomBaseAdapterOne adapter1 = null;
private CustomBaseAdapterTwo adapter2 = null;
public GlobalConfig getAdapterOne() {return adapter1;}
public GlobalConfig getAdapterTwo() {return adapter2;}
public static synchronized GlobalConfig getInstance() {
if (config == null) {
config = new GlobalConfig();
config.adapter1 = new CustomBaseAdapterOne();
config.adapter2 = new CustomBaseAdapterTwo();
}
return config;
}
}
您的ListViewActivity将需要扩展DataSetObserver类并在启动时注册一个观察器。您的CustomListAdapter启动时需要注册观察者,并且还需要能够通过函数(例如setContext)(而不是通过构造函数)使用初始化参数(在您的情况下为Context)进行初始化,因此在ListViewActivity中,将需要执行以下操作:
GlobalConfig cfg = GlobalConfig.getInstance();
CustomerAdapterOne ad = cfg.getAdapterOne();
ad.setContext(this);
ad.registerDataSetObserver(this);
从需要更新ListView的单独线程中,将运行:
GlobalConfig cfg = GlobalConfig.getInstance();
try {
cfg.getAdapterOne().notifyDataSetChanged();
}
catch{... }
我认为,在此处尝试/捕获是个好主意,因为我不知道如果ListView在需要通知时已经死亡,将会发生什么。
总结一下:您需要为每个需要更新的视图预先创建一个适配器,并将其全局提供给所有需要它的人。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句