更新ListView行中的UI元素不起作用

时间:2013-12-06 14:01:43

标签: android android-layout android-listview

我正在尝试从自定义适配器更新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()。有什么想法吗?

2 个答案:

答案 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一样简单。