Search code examples
javaandroidarraylistandroid-asynctask

Arraylist not working, items do not stack up


So, I am trying to get some info from database and save it into an ArrayList, so later I can add dinamically buttons according to the length and items from that list.

code:

private List<String> probleme = new ArrayList<>();

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

    if (SharedPrefManager.getInstance(this).isLoggedIn()) {
        CautaProbleme();
        for(int i=0; i<probleme.size(); i++) {
            Button myButton = new Button(this);
            myButton.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
            myButton.setText(probleme.get(i));
            LinearLayout layout = (LinearLayout) findViewById(R.id.linear_home);
            layout.addView(myButton);
        }
    }`

CautaProbleme method:

private void CautaProbleme(){
    class CautaProbleme extends AsyncTask<Void, Void, String> {
        User user = SharedPrefManager.getInstance(getApplicationContext()).getUser();
        final String departament = String.valueOf(user.getDepartament());
        @Override
        protected String doInBackground(Void... voids) {
            //creating request handler object
            RequestHandler requestHandler = new RequestHandler();

            //creating request parameters
            HashMap<String, String> params = new HashMap<>();
            params.put("departament", departament);

            //returing the response
            return requestHandler.sendPostRequest(URLs.URL_PROBLEME, params);
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            //displaying the progress bar while user registers on the server
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            //hiding the progressbar after completion

            try {
                //converting response to json object
                JSONObject obj = new JSONObject(s);

                //if no error in response
                if (!obj.getBoolean("error")) {
                    JSONArray problemeArray = obj.getJSONArray("probleme");
                    for (int i = 0; i < problemeArray.length(); i++) {
                        JSONObject problema = problemeArray.getJSONObject(i);
                        // Verificare daca s-au primit probleme trimise de server
                        if (!problema.isNull("Problema")) {
                            String situatie = problema.getString("Problema");
                            probleme.add(situatie);
                        }
                    }

                } else {
                    Toast.makeText(getApplicationContext(), "Some error occurred", Toast.LENGTH_SHORT).show();
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
    CautaProbleme ru =new CautaProbleme();
    ru.execute();
}

The JSON response it's alright, the problemeArray looks good, but the problem it's that the .add() command does not add the strings to the list, so the for for creating buttons does not do anything, having an empty list. I have declared private List probleme = new ArrayList<>(); globally.


Solution

  • AsyncTask executes asynchronously, so you have to wait till finish the execution to get data. Better options is to use a callback to invoke when operation completed.

    Step - 1: Remove button creation code from onCreate and add it in callback

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
        ....
    
        if (SharedPrefManager.getInstance(this).isLoggedIn()) {
            CautaProbleme();
        }
    }
    

    Add callback function and update logic here

    private void createButtonDynamically() {
        LinearLayout layout = (LinearLayout) findViewById(R.id.linear_home);
    
        for (int i = 0; i < probleme.size(); i++) {
            Button myButton = new Button(this);
            myButton.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
            myButton.setText(probleme.get(i));
            layout.addView(myButton);
        }
    }
    

    Step - 2: Invoke callback from onPostExecute when operation finish

    class CautaProbleme extends AsyncTask<Void, Void, String> {
    
        ....
    
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
    
            ....
    
            createButtonDynamically();
        }
    }