我无法从 ListView 的转移中更改CheckedTextView
复选框的状态。SimpleAdapter::getView()
我也试过CheckedTextView.invalidate()
没有效果。
我将列表元素的状态存储在一个单独的容器中:gather_data
- 整个源代码在
- V2:http://pastebin.com/kQU0qQvU(添加
notifyDataSetChanged()
) - V1:http://pastebin.com/Q17uvXaN(原创)
- V2:http://pastebin.com/kQU0qQvU(添加
- 用于 ListView 的布局:http: //pastebin.com/UtF4ZFNn
当前代码:
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()");
}
}