0

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.

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

9 Comments

That's definitely a possibility I hadn't thought of. Would you care to take a stab at writing the code for that?
It does, you want me to essentially create a method that returns Result and make the scope cover my if-else statements. Now that is the Result from the javax.transform.xml library, correct?
Well, Result would it's own class that you make, not from any existing library - responsible for encapsulating all the data you need. So it's a class that has fields of strings, etc, whatever it is you need. It's sole purpose is just to hold information for you to access later. Call it whatever you like :)
You need to set layout parameters on all your views. (stackoverflow.com/questions/2395769/…)
See @torbenkohlmeier's answer. You're not using the Result you built..You need to change your AsyncTask to extends AsyncTask<String, String, Result> and return Result...currently you return null...
|
1

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.