问题
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