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.

i_me_mine
  • 1,435
  • 3
  • 20
  • 42

2 Answers2

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.

Ken Wolf
  • 23,133
  • 6
  • 63
  • 84
  • That's definitely a possibility I hadn't thought of. Would you care to take a stab at writing the code for that? – i_me_mine Jun 02 '13 at 19:33
  • 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? – i_me_mine Jun 02 '13 at 19:40
  • 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 :) – Ken Wolf Jun 02 '13 at 19:43
  • Ha, nevermind I misread the code, you actually want me to instantiate an object called Response and then return that, sorry. There are 3 libraries that actually hold built in methods called "Response". I was just overthinking it. Yes makes perfect sense. I will test it and let you know – i_me_mine Jun 02 '13 at 19:43
  • I edited my post, the errors are gone but my screen is blank except the save button I make visible – i_me_mine Jun 02 '13 at 20:13
  • 1
    You need to set layout parameters on all your views. (http://stackoverflow.com/questions/2395769/how-to-programmatically-add-views-to-views) – Ken Wolf Jun 02 '13 at 20:16
  • edited post again.. still blank. Could it be `Result` is not returning any values? Or is it that when I create new `LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT))` I should be setting it to `ll` or `ll1.layoutParams` – i_me_mine Jun 02 '13 at 20:28
  • 1
    See @torbenkohlmeier's answer. You're not using the `Result` you built..You need to change your AsyncTask to `extends AsyncTask` and return Result...currently you return `null`... – Ken Wolf Jun 02 '13 at 20:31
  • We are on the same page, I was just about to say that. It's time for a new question if I can't figure this out. Thanks Ken, you've been very helpful. – i_me_mine Jun 02 '13 at 20:32
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.

Torben Kohlmeier
  • 6,713
  • 1
  • 15
  • 15