问题
I am attempting to parse a JSON response from a PHP file and then use the data to create a series of RadioButton, EditText, CheckBox, and DropDownMenu elements inside a layout. In other words a dynamic or "on the fly" layout. I'm currently receiving the JSON I need but the app is crashing.
AsyncTask
class LoadAllQuestions extends AsyncTask<String, String, String> {
private ProgressDialog pDialog;
JSONParser jParser = new JSONParser();
JSONArray questions = null;
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Loading questions. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
protected String doInBackground(String... args) {
// getting JSON string from URL
companyName = cn.getText().toString();
projectName = pn.getText().toString();
String componentName = (String) ab.getSelectedTab().getText();
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3);
nameValuePairs.add(new BasicNameValuePair("company", companyName));
nameValuePairs.add(new BasicNameValuePair("project", projectName));
nameValuePairs.add(new BasicNameValuePair("component",
componentName));
JSONObject json = jParser.makeHttpRequest(url, "POST",
nameValuePairs);
// Check your log cat for JSON response
Log.d("All Questions: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found: getting Array of Questions
questions = json.getJSONArray(TAG_QUESTIONS);
// looping through All Questions
for (int i = 0; i < questions.length(); i++) {
JSONObject c = questions.getJSONObject(i);
// Storing each JSON item in variable
String name = c.getString(TAG_NAME);
String field = c.getString(TAG_FIELD);
String value = c.getString(TAG_VALUE);
Result result = null;
if (field == r) {
result = new Result();
result.setType(1);
result.setName(name);
result.setField(field);
result.setValue(value);
} else {
result = new Result();
result.setType(2);
result.setName(name);
result.setField(field);
result.setValue(value);
}
}
} else {
// no products found
Log.v("ERROR", "No JSON for you!");
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog
pDialog.dismiss();
Result result = new Result();
if (result.getType() == 1) {
LinearLayout content = (LinearLayout) view
.findViewById(R.id.genA_layout);
// create
TextView tv = new TextView(getActivity());
RadioGroup rg = new RadioGroup(getActivity());
rg.setOrientation(RadioGroup.HORIZONTAL);
RadioButton rb = new RadioButton(getActivity());
RadioButton rb2 = new RadioButton(getActivity());
LinearLayout ll = new LinearLayout(getActivity());
// set
rb.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
rb2.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
ll.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
rb.setText(result.getValue());
rb2.setText(result.getValue());
tv.setText(result.getName());
ll.setOrientation(LinearLayout.HORIZONTAL);
// add
rg.addView(rb);
rg.addView(rb2);
ll.addView(tv);
ll.addView(rg);
content.addView(ll);
} else if (result.getType() == 2) {
// find
LinearLayout content = (LinearLayout) view
.findViewById(R.id.genA_layout);
// create
TextView tv = new TextView(getActivity());
EditText et = new EditText(getActivity());
LinearLayout ll1 = new LinearLayout(getActivity());
// set
tv.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
et.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
ll1.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
tv.setText(result.getName());
ll1.setOrientation(LinearLayout.HORIZONTAL);
// add
ll1.addView(tv);
ll1.addView(et);
content.addView(ll1);
}
// find
LinearLayout loader = (LinearLayout) view
.findViewById(R.id.loader_layout);
Button save = (Button) view
.findViewById(R.id.generalAssets_save_button_ID);
// set
loader.setVisibility(View.GONE);
save.setVisibility(View.VISIBLE);
};
}
}
JSON
{
"questions": [
{
"display_name": "Store #",
"field_type": "Text Field",
"option_value": ""
},
{
"display_name": "Address",
"field_type": "Text Field",
"option_value": ""
},
{
"display_name": "Type of Business",
"field_type": "Drop Down Menu",
"option_value": "Education\r\nHealth\r\nComputers\r\nFood\r\nRetail\r\nOther"
},
{
"display_name": "Is this business good?",
"field_type": "Radio",
"option_value": "Yes\r\nNo"
},
{
"display_name": "Are they nice people?",
"field_type": "Check Box",
"option_value": "Yes\r\nNo"
}
],
"success": 1
}
Result Class
public class Result {
private String name;
private String field;
private String value;
private int type;
//constructor
public Result() {
}
// <-----SET METHODS----->
public void setName(String name) {
name = this.name;
}
public void setField(String field) {
field = this.field;
}
public void setValue(String value) {
value = this.value;
}
public void setType(int type) {
type = this.type;
}
// <-----GET METHODS----->
public String getName() {
return name;
}
public String getField() {
return field;
}
public String getValue() {
return value;
}
public int getType() {
return type;
}
}
If you would like the XML just ask.
Edit
Edited my post from suggestions. Thanks @Ken Wolf. The errors are gone but now my fragment is blank.
回答1:
You are right, you shouldn't be changing the UI in doInBackground.
Can't you encapsulate everything you need in some kind of transfer Object, set the result accordingly, and do everything in onPostExecute?
Example:
protected String doInBackground(String... args) {
...
Result result = null;
if (field == r) {
result = new Result();
result.setType(1);
result.setValue(value);
result.setName(name);
... // store whatever else you need
}
else {
result.setType(2);
... // store whatever else you need
}
return result;
}
protected void onPostExecute(Result result) {
if (result.getType() == 1)
// build layout
else if (result.getType() == 2)
// build layout
}
Of course, make the Result class more meaningful to you and your data.
回答2:
You create a new (empty) Result object in onPostExecute. You need to use the Result object you created in doInBackground, for example by adding a Result field in the AsyncTasc, assign it in doInBackground and use it in onPostExecute.
Edit: If you are not using the parameter file_url in inPostExecute, you should change it to Result and return the result object in doInBackground.
来源:https://stackoverflow.com/questions/16886437/create-multiple-layouts-from-json