CheckedTextView使用适配器更改状态

时间:2013-02-03 12:30:50

标签: java android listview simpleadapter

我无法从ListView中更改CheckedTextView转移的SimpleAdapter::getView()复选框的状态。我也尝试了CheckedTextView.invalidate()而没有效果。

我将列表元素的状态存储在一个单独的容器中:gather_data

当前代码:

package org.raboss.gamification.scavengerhunt;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
import android.widget.Button;
import android.widget.CheckedTextView;
import android.widget.SimpleAdapter;
import android.widget.SimpleCursorAdapter;
import android.app.Activity;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Color;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ListView;
import android.util.Log;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GatherListActivity extends Activity {

    protected ListView gather_list;
    protected AsyncQueryHandler asyncGatherlistQueryHandler;
    private SharedPreferences prefs;
    protected ArrayList<HashMap<String,Object>> gather_data;

    final private int INTENT_REQUESTCODE_QRSCAN = 1;

    private class CheckedListAdapter extends SimpleAdapter {

        public CheckedListAdapter(Context context,
                List<? extends Map<String, ?>> data, int resource,
                String[] from, int[] to) {
            super(context, data, resource, from, to);
            // TODO Auto-generated constructor stub
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = super.getView(position, convertView, parent);
            if (parent != null) {
                CheckedTextView ctv = (CheckedTextView)parent.findViewById(android.R.id.text1);
                if (ctv != null) {
                    try {
                        if (position < gather_data.size()) {
                            HashMap<String,Object> hm = gather_data.get(position);
                            if (ctv.isChecked() != (Boolean)hm.get("mark")) {
                                Log.v(this.getClass().getName(), String.format("Draw %s->%s %s", ctv.isChecked() ? "set" : "unset", (Boolean)hm.get("mark") ? "set" : "unset", hm.get("context")));
                                //ctv.setChecked((Boolean)hm.get("mark"));
                                //parent.invalidate();
                                ctv.toggle();
                            }
                            ctv.setTextColor(ctv.isChecked() ? Color.GREEN : Color.BLACK);
                        }
                    }
                    catch (Exception ex) {
                        Log.v(this.getClass().getName(), ex.toString());
                    }
                }
            }
            return v;
        }
    }

    protected CheckedListAdapter gatherlist_adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gatherlist);
        Log.v(this.getClass().getName(), "onCreate()");

        internalRestoreInstanceState(savedInstanceState);

        String[] from = new String[] {"title", "context"};
        int[] to = new int[] {android.R.id.text1, android.R.id.text2};
        try {
            gather_list = (ListView)findViewById(R.id.gather_list);
            gatherlist_adapter = new CheckedListAdapter(gather_list.getContext(), this.gather_data, R.layout.gather_list_item, from, to);
            ListView lv = (ListView)this.findViewById(R.id.gather_list);
            lv.setAdapter(gatherlist_adapter);
        }
        catch (IllegalArgumentException ex) {
            Log.e(this.getClass().getName(), ex.toString());    
            throw(ex);
        }

        Button qrscanner_button = (Button)findViewById(R.id.qrscanner_button);
        qrscanner_button.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Log.v(this.getClass().getName(), "onClick()");
                Intent intent = new Intent("org.raboss.gamification.scavengerhunt.SCAN");
                intent.putExtra("EMBEDDED_INTENT", true);
                intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
                startActivityForResult(intent, INTENT_REQUESTCODE_QRSCAN);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != RESULT_OK)
            return;

        switch (requestCode) {
        case INTENT_REQUESTCODE_QRSCAN:
            onActivityResultQRScan(resultCode, data);
            break;
        }
    }

    private void onActivityResultQRScan(int resultCode, Intent data) {
        // Handle successful scan
        String contents = data.getStringExtra("SCAN_RESULT");
        Log.i(this.getClass().getName(), "Scanned QR-Code: "+contents);

        try {
            Uri link = Uri.parse(contents);
            String link_where = link.getQueryParameter("where");
            Log.i(this.getClass().getName(), String.format("Stand: %s", link_where));
            for(HashMap<String,Object> hm : this.gather_data) {
                String context = (String)hm.get("context");
                if (context.contains(link_where)) {
                    hm.put("mark", Boolean.TRUE);
                }
                else if (link_where.contains("restart")) {
                    hm.put("mark", Boolean.FALSE);
                }
                Log.i(this.getClass().getName(), String.format("%s ~ %s: %s", context, link_where, (Boolean)hm.get("mark") ? "set" : "unset"));
            }
            if (this.gatherlist_adapter != null) {
                this.gatherlist_adapter.notifyDataSetChanged();
            }
        }
        catch (Exception ex) {
            Log.i(this.getClass().getName(), ex.toString());
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.v(this.getClass().getName(), "onSaveInstanceState()");
        this.internalSaveInstanceState(outState);
    }

    protected void internalSaveInstanceState(Bundle outState) {
        Log.v(this.getClass().getName(), "internalSaveInstanceState()");
        prefs = getSharedPreferences(this.getClass().getName(), MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        try {
            for(HashMap<String,Object> hm : this.gather_data) {
                editor.putBoolean((String)hm.get("context"), (Boolean)hm.get("mark"));          
            }
        }
        catch (Exception ex) {
            Log.v(this.getClass().getName(), ex.toString());
        }
        editor.commit();
    }


    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.v(this.getClass().getName(), "onRestoreInstanceState()");
        this.internalRestoreInstanceState(savedInstanceState);
    }

    protected void internalRestoreInstanceState(Bundle savedInstanceState) {
        Log.v(this.getClass().getName(), "internalRestoreInstanceState()");
        if (this.gather_data != null) {
            Log.v(this.getClass().getName(), String.format("this.gather_data already initialised: %d", gather_data.size()));
        }
        else {
            Resources res = getResources();
            String[] cebit_stands = res.getStringArray(R.array.cebit_stands);
            String[] go_slogen = res.getStringArray(R.array.go_slogan);
            this.gather_data = new ArrayList<HashMap<String,Object>>();
            for (int i = 0; i < cebit_stands.length; i++) {
                HashMap<String, Object> hm = new HashMap<String, Object>();
                hm.put("context", cebit_stands[i]);
                hm.put("title", go_slogen[i % go_slogen.length]);
                this.gather_data.add(hm);
            }
        }
        prefs = getSharedPreferences(this.getClass().getName(), MODE_PRIVATE);
        try {
            for(HashMap<String,Object> hm : this.gather_data) {
                hm.put("mark", prefs.getBoolean((String)hm.get("context"), Boolean.FALSE));
                Log.v(this.getClass().getName(), String.format("Restore %s = %s", (String)hm.get("context"), (Boolean)hm.get("mark") ? "set" : "unset"));
            }
        }
        catch (Exception ex) {
            Log.v(this.getClass().getName(), ex.toString());
        }
    }

    @Override
    public void finish() {
        Log.v(this.getClass().getName(), "finish()");
    }
}

1 个答案:

答案 0 :(得分:0)

感谢您的时间。与此同时,我发现了错误。这是解决方案:

    public View getView(int position, View convertView, ViewGroup parent) {
    CheckedTextView ctv = null;
    if (convertView != null) {
        ctv = (CheckedTextView)convertView.findViewById(android.R.id.text1);
    }
    if (ctv != null) {

使用notifyDataSetChanged()并非强制要求。解决方案是使用convertView参数而不是parent来查找CheckedTextView中的正确ListView元素。