Christopher Tan
Christopher Tan

Reputation: 345

populate json array data into android dynamic spinner

I'm fairly new to android and I'm just two months or so on it, so please be nice =) I'm getting error at string result due to String [] items are required to populate on Array adapter adapter.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_select_class);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    /**dropdown start**/
    populatedata();
    spinnercall(result);
    /**dropdown end**/
}

private void spinnercall(result) {

    Spinner dynamicSpinner = (Spinner) findViewById(R.id.dynamic_spinner);

    //String[] items = new String[] { "Chai Latte", "Green Tea", "Black Tea" };
    String items = result;

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, items);

    dynamicSpinner.setAdapter(adapter);

    dynamicSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            Log.v("item", (String) parent.getItemAtPosition(position));
        }
        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            // TODO Auto-generated method stub
        }
    });

}

private String populatedata() {
    try{
        SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
        String userid =pref.getString("userid", "null");

        String link="selectclass.php";
        String data  = URLEncoder.encode("id", "UTF-8") + "=" + URLEncoder.encode(userid, "UTF-8");

        URL url = new URL(link);
        URLConnection conn = url.openConnection();

        conn.setDoOutput(true);
        OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());

        wr.write( data );
        wr.flush();

        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

        StringBuilder sb = new StringBuilder();
        String line = null;

        // Read Server Response
        while((line = reader.readLine()) != null)
        {
            sb.append(line);
            break;
        }

        result = sb.toString();
        return result;
    }
    catch(Exception e){
        String errorno;
        errorno = ("Exception: " + e.getMessage());
        Toast.makeText(getApplicationContext(), errorno, Toast.LENGTH_SHORT).show();
    }

}

this is my selectclass.php code

$sql = "SELECT subejct_id, subject_name FROM class_schedule where subject_lec = '$id'";
$res = $conn->query($sql);
$result = array();

if ($res->num_rows > 0) {
    // output data of each row
    while($row = $res->fetch_array()){

      array_push($result, array('subject_id'=>$row[0], 'subject_name'=>$row[1]));

      echo json_encode(array("result"=>$result));
    }  
} else {
    echo "fail";
}

on clearer Problem explain, the problem I encountered is at

// Read Server Response
        while((line = reader.readLine()) != null)
        {
            sb.append(line);
            break;
        }
    result = sb.toString();
    return result;
}

and

//String[] items = new String[] { "Chai Latte", "Green Tea", "Black Tea" };
    String items = result;

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, items);

while the // works perfectly but i do not want hardcoded arrays.

Upvotes: 0

Views: 2033

Answers (2)

Christopher Tan
Christopher Tan

Reputation: 345

I solved using json object decoder

try{
            JSONObject person = new JSONObject(result);
            JSONArray jsonMainNode = person.getJSONArray("result");
            final int n = jsonMainNode.length();

            //List<Map<String,String>> classList = new ArrayList<Map<String,String>>();
            final ArrayList<HashMap> classList = new ArrayList<>();
            String[] spinnerArray = new String[n];
            HashMap<String,String> spinnerMap = new HashMap<>();

            for(int i = 0; i< n; i++){
                JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);

                String schedule_id = jsonChildNode.getString("schedule_id");
                String subject_name = jsonChildNode.getString("subject_name");

                spinnerMap.put(schedule_id, subject_name);
                classList.add(spinnerMap);

                String total = "Class Section : "+schedule_id+" "+subject_name;
                spinnerArray[i] = total;
            }

            Spinner dynamicSpinner = (Spinner) findViewById(R.id.dynamic_spinner);
            ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, spinnerArray);
            dynamicSpinner.setAdapter(adapter);

            dynamicSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    String classid = classList.get(position);
                    Log.v("item", (String) parent.getItemAtPosition(position));
                }
                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                    // TODO Auto-generated method stub
                }
            });
        }
        catch(JSONException e){
            Toast.makeText(getApplicationContext(), "Error"+e.toString(), Toast.LENGTH_SHORT).show();
        }

Upvotes: 1

Gary Bak
Gary Bak

Reputation: 4798

Assuming your json looks like this:

[{"subject_id":"123","subject_name":"123Name"},{"subject_id":"123","subject_name":"123Name"}]

You can parse it to an array with this code:

Gson gson = new Gson();
Subject[] items = gson.fromJson(jsonString, Subject[].class);

With this help of this object class:

class Subject {
    public String subject_id = "";
    public String subject_name = "";
}

This will not work directly with the ArrayAdapter though, you will either need a custom adapter to pull out only the value you want, or create a new array with just the subject_name values.

As also mentioned in other comments, using a library to make your REST calls will simplify your code and make it much more resilient. Here is an example using Volley:

String url = "http://address/path";
RequestQueue queue = Volley.newRequestQueue(appContext);

StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
              new Response.Listener<String>() {
                  @Override
                  public void onResponse(String response) {

                      Log.d("TAG", "success, parse your json here: " + response);
                      // Populate your ArrayList
                      // notify adapter of the dataset change
                  }
              }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });

 queue.add(stringRequest);

Update (Adding list of async http libraries):

Volley is from Google

Retrofit is a community offering from Square

Android Aysnc - Open source offering from James Smith

Upvotes: 1

Related Questions