I am attempting to update UI elements in a ListView row from my custom adapter. I have no problems when updating from within getView(). But the UI does not update from within my onCheckedChangedListener nor from a method called in onPostExecute() of my AsyncTask. I am using the View Holder pattern, here is my code.
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);
}
}
I had put in logging statements, and updateResult() is definitely being called correctly. Any ideas?