我是一个使用ArrayAdapter在屏幕上显示复选框和微调器的活动,具体取决于xml中的定义。 用户检查所需的复选框并从所需的微调器中选择并单击“保存”。
,当屏幕上看不到微调器时(由于滚动),我的问题就出现了。我的代码:
public class DetailsActivity extends Activity {
InputStream DetailsFile;
Map<String, List<String>> details;
ListView list;
String[] titlesArray;
ArrayList<String> types;
HashMap<Integer, Integer> spinnerPositions = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
AssetManager am = this.getAssets();
try {
DetailsFile = am.open("Details.xml");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
types = new ArrayList<String>();
details = ParseDetailsXML(DetailsFile);
Set<String> keys = details.keySet();
titlesArray = keys.toArray(new String[keys.size()]);
list = (ListView) findViewById(R.id.list_view);
DetailsAdapter adapter = new DetailsAdapter(this, titlesArray, details,
types);
list.setAdapter(adapter);
}
public Map<String, List<String>> ParseDetailsXML(InputStream is) {
LinkedHashMap<String, List<String>> map = new LinkedHashMap<String, List<String>>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();
Document doc = builder.parse(is, "UTF-8");
Element root = doc.getDocumentElement();
NodeList children = root.getChildNodes();
List<String> detailList = null;
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child instanceof Element) {
Element childElement = (Element) child;
this.types.add(childElement.getAttribute("type"));
NodeList details = childElement.getChildNodes();
String detail = childElement.getNodeName();
detailList = new LinkedList<String>();
if (childElement.getAttribute("type").equalsIgnoreCase("dropdown")) {
detailList.add("No Selection");
}
for (int j = 0; j < details.getLength(); j++) {
Node detailND = details.item(j);
if (detailND instanceof Element) {
Element detailElement = (Element) detailND;
String text = detailElement.getAttribute("val");
detailList.add(text);
}
}
map.put(detail, detailList);
}
}
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
;
return map;
}
public class DetailsAdapter extends ArrayAdapter<String> {
Context context;
String[] titleArray;
Map<String, List<String>> details;
List<String> types;
DetailsAdapter(Context c, String[] titles,
Map<String, List<String>> details, List<String> types) {
super(c, R.layout.details_single_row, R.id.text_view, titles);
this.context = c;
this.titleArray = titles;
this.details = details;
this.types = types;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
String mCurrentType = types.get(position);
if (mCurrentType.contains("checkbox")) {
View row = inflater.inflate(R.layout.details_single_row,
parent, false);
TextView myTitle = (TextView) row.findViewById(R.id.text_view);
ViewGroup checkBoxContainer = (ViewGroup) row
.findViewById(R.id.checkBoxContainer);
myTitle.setText(titleArray[position]);
List<String> checkBoxTitles = details.get(titleArray[position]);
int i = 1;
for (String value : checkBoxTitles) {
CheckBox checkbox = new CheckBox(context);
checkbox.setId(i);
checkbox.setText(value);
checkbox.setTextSize(35);
checkBoxContainer.addView(checkbox);
i++;
}
return row;
} else {
View row = inflater.inflate(
R.layout.details_single_row_dropdown, parent, false);
TextView myTitle = (TextView) row.findViewById(R.id.textView1);
myTitle.setText(titleArray[position]);
List<String> spinnerTitles = details.get(titleArray[position]);
Spinner spinner = (Spinner) row
.findViewById(R.id.spinner_details);
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(
context, android.R.layout.simple_dropdown_item_1line,
spinnerTitles);
spinnerArrayAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(spinnerArrayAdapter);
spinner.setGravity(Gravity.CENTER);
return row;
}
}
}
public void SaveButton(View v) {
myGlobals.Details = new LinkedHashMap<String, ArrayList<String>>();
myGlobals.Accessories = null;
spinnerPositions = new HashMap<Integer, Integer>();
ListView list = (ListView) findViewById(R.id.list_view);
View row;
CheckBox checkbox = null;
List<String> titles = new ArrayList<String>(details.keySet());
for (int i = 0; i < list.getCount(); i++) {
String title = titles.get(i); // title
List<String> valueList = details.get(title); // the list ascosiated
// with that title
row = list.getChildAt(i);
String type = types.get(i);
if (type.contains("checkbox")) {
ArrayList<String> checkedTitles = new ArrayList<String>();
ViewGroup checkBoxContainer = (ViewGroup) row
.findViewById(R.id.checkBoxContainer);
for (int j = 0; j < checkBoxContainer.getChildCount(); j++) {
checkbox = (CheckBox) checkBoxContainer.findViewById(j + 1);
if (checkbox.isChecked()) {
String checkBoxTitle = checkbox.getText().toString();
checkedTitles.add(checkBoxTitle);
}
}
if (!checkedTitles.isEmpty()) {
myGlobals.Details.put(title, checkedTitles);
}
} else {
ArrayList<String> selectedItem = new ArrayList<String>();
Spinner spinner = (Spinner) row
.findViewById(R.id.spinner_details);
spinnerPositions.put(i, spinner.getSelectedItemPosition());
String selected = spinner.getSelectedItem().toString();
selectedItem.add(selected);
myGlobals.Details.put(title, selectedItem);
}
}
Toast toast = Toast.makeText(this, "Accesories Saved!",
Toast.LENGTH_SHORT);
toast.show();
StringBuilder sb = new StringBuilder("");
for (Map.Entry<String, ArrayList<String>> entry : myGlobals.Details
.entrySet()) {
String key = entry.getKey();
ArrayList<String> list2 = entry.getValue();
String joined = TextUtils.join(",", list2);
sb.append(key + " : " + joined + " . ");
myGlobals.Accessories = sb.toString();
}
Log.d("YANIV", myGlobals.Accessories);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putStringArrayList("types", types);
outState.putStringArray("titlesArray", titlesArray);
outState.putSerializable("spinnerPositions", spinnerPositions);
for (Entry<String, ArrayList<String>> entry : myGlobals.Details
.entrySet()) {
String key = entry.getKey();
ArrayList<String> list = entry.getValue();
outState.putStringArrayList(key, list);
}
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
String[] titles = savedInstanceState.getStringArray("titlesArray");
ArrayList<String> typesArrayList = savedInstanceState
.getStringArrayList("types");
spinnerPositions = (HashMap<Integer, Integer>) savedInstanceState
.getSerializable("spinnerPositions");
for (String value : typesArrayList) {
ListView list = (ListView) findViewById(R.id.list_view);
View row;
CheckBox checkbox = null;
for (int i = 0; i < list.getCount(); i++) {
String currentTitle = titles[i];
ArrayList<String> currentList = savedInstanceState
.getStringArrayList(currentTitle);
row = list.getChildAt(i);
if (value.contains("checkbox")) {
ViewGroup checkBoxContainer = (ViewGroup) row
.findViewById(R.id.checkBoxContainer);
for (int j = 0; j < checkBoxContainer.getChildCount(); j++) {
checkbox = (CheckBox) checkBoxContainer
.findViewById(j + 1);
if (currentList.contains(checkbox.getText())) {
checkbox.setChecked(true);
}
}
} else {
Spinner spinner = (Spinner) row
.findViewById(R.id.spinner_details);
spinner.setSelection(spinnerPositions.get(i));
}
}
}
super.onRestoreInstanceState(savedInstanceState);
}
}
我的logcat崩溃:
06-14 17:15:03.013: E/AndroidRuntime(10109): FATAL EXCEPTION: main
06-14 17:15:03.013: E/AndroidRuntime(10109): Process: com.tfl.techmanager, PID: 10109
06-14 17:15:03.013: E/AndroidRuntime(10109): java.lang.IllegalStateException: Could not execute method of the activity
06-14 17:15:03.013: E/AndroidRuntime(10109): at android.view.View$1.onClick(View.java:3823)
06-14 17:15:03.013: E/AndroidRuntime(10109): at android.view.View.performClick(View.java:4438)
06-14 17:15:03.013: E/AndroidRuntime(10109): at android.view.View$PerformClick.run(View.java:18422)
06-14 17:15:03.013: E/AndroidRuntime(10109): at android.os.Handler.handleCallback(Handler.java:733)
06-14 17:15:03.013: E/AndroidRuntime(10109): at android.os.Handler.dispatchMessage(Handler.java:95)
06-14 17:15:03.013: E/AndroidRuntime(10109): at android.os.Looper.loop(Looper.java:136)
06-14 17:15:03.013: E/AndroidRuntime(10109): at android.app.ActivityThread.main(ActivityThread.java:5001)
06-14 17:15:03.013: E/AndroidRuntime(10109): at java.lang.reflect.Method.invokeNative(Native Method)
06-14 17:15:03.013: E/AndroidRuntime(10109): at java.lang.reflect.Method.invoke(Method.java:515)
06-14 17:15:03.013: E/AndroidRuntime(10109): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
06-14 17:15:03.013: E/AndroidRuntime(10109): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
06-14 17:15:03.013: E/AndroidRuntime(10109): at dalvik.system.NativeStart.main(Native Method)
06-14 17:15:03.013: E/AndroidRuntime(10109): Caused by: java.lang.reflect.InvocationTargetException
06-14 17:15:03.013: E/AndroidRuntime(10109): at java.lang.reflect.Method.invokeNative(Native Method)
06-14 17:15:03.013: E/AndroidRuntime(10109): at java.lang.reflect.Method.invoke(Method.java:515)
06-14 17:15:03.013: E/AndroidRuntime(10109): at android.view.View$1.onClick(View.java:3818)
06-14 17:15:03.013: E/AndroidRuntime(10109): ... 11 more
06-14 17:15:03.013: E/AndroidRuntime(10109): Caused by: java.lang.NullPointerException
06-14 17:15:03.013: E/AndroidRuntime(10109): at com.tfl.techmanager.DetailsActivity.SaveButton(DetailsActivity.java:226)
06-14 17:15:03.013: E/AndroidRuntime(10109): ... 14 more
它崩溃了:
Spinner spinner = (Spinner) row
.findViewById(R.id.spinner_details);
并且由于滚动而导致微调器在屏幕上不可见时发生崩溃(但它可用)