我正在尝试从自定义适配器更新ListView行中的UI元素。从getView()内部更新时没有问题。但UI不会从我的onCheckedChangedListener中更新,也不会从我的AsyncTask的onPostExecute()中调用的方法更新。我正在使用View Holder模式,这是我的代码。
public class InstanceAdapter extends ArrayAdapter<MyInstance> {
Context context;
int layoutResourceId;
List<MyInstance> data = null;
static InstanceHolder holder = null;
static Timer myTimer;
public InstanceAdapter(Context context, int layoutResourceId,
List<MyInstance> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new InstanceHolder();
holder.spinner = (ProgressBar) row.findViewById(R.id.progressBar);
holder.state = (TextView) row.findViewById(R.id.instanceState);
row.setTag(holder);
} else {
holder = (InstanceHolder) row.getTag();
}
final MyInstance instance = data.get(position);
holder.instanceName.setText(instance.getName());
holder.state.setText(instance.getState());
holder.toggle.setChecked(instance.stateSwitch);
holder.toggle.setEnabled(instance.getEnabled());
holder.toggle.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
// this does not work
holder.spinner.setVisibility(View.VISIBLE);
new StartInstancesTask(instance).execute();
} else {
// this does not work
holder.spinner.setVisibility(View.VISIBLE);
}
}
});
return row;
}
@Override
public MyInstance getItem(int position) {
return data.get(position);
}
static class InstanceHolder {
TextView state;
ProgressBar spinner;
}
protected static class StartInstancesTask extends
AsyncTask<Void, Void, String> {
private MyInstance instance;
private String result;
public StartInstancesTask(MyInstance instance) {
this.instance = instance;
}
@Override
protected String doInBackground(Void... params) {
result = EC2.startInstance(instance.getId());
return result;
}
protected void onPostExecute(final String result) {
updateState(result);
}
}
public static void updateState(String result) {
// these ui updates do not work ...
if (result.equals("pending")) {
holder.spinner.setVisibility(View.VISIBLE);
} else if (result.equals("running")) {
holder.spinner.setVisibility(View.GONE);
} else if (result.equals("shutting-down")) {
holder.spinner.setVisibility(View.VISIBLE);
} else if (result.equals("terminated")) {
holder.spinner.setVisibility(View.GONE);
} else if (result.equals("stopping")) {
holder.spinner.setVisibility(View.VISIBLE);
} else if (result.equals("stopped")) {
holder.spinner.setVisibility(View.GONE);
}
holder.state.setText(result);
}
}
我已经输入了日志记录语句,并且肯定正确地调用了updateResult()。有什么想法吗?
答案 0 :(得分:0)
使用holder.toggle.setTag
获取点击行的持有者实例以更新视图。试试:
InstanceHolder clicked_holder = null; // to get selected row views
<{1>} getView
使用holder
保存当前行holder.toggle.setTag
:
holder.toggle.setEnabled(instance.getEnabled());
holder.toggle.setTag(holder);
holder.toggle.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
clicked_holder=(InstanceHolder)buttonView.getTag();
//...your code here..
}
});
现在使用clicked_holder
代替holder
,其中最后一行包含所选行中的更新视图
答案 1 :(得分:0)
看一下这篇文章: http://android.kuffs.co.uk/2013/12/custom-list-adapter-with-icon-and.html
在这种情况下更新UI就像编辑CheckedListItem(或类似)类的属性并在适配器上调用NotifyDatasetChanged
一样简单。