Filtering ListView IndexOutOfBoundsException

89 Views Asked by At

After writing inside the EditText i get this exception:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: android_team.gymme_client, PID: 7500
    java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        at java.util.ArrayList.get(ArrayList.java:437)
        at android_team.gymme_client.gym.CustomGymTrainerAdapter.getView(CustomGymTrainerAdapter.java:50)
        at android.widget.AbsListView.obtainView(AbsListView.java:2387)
        at android.widget.ListView.makeAndAddView(ListView.java:2067)
        at android.widget.ListView.fillDown(ListView.java:793)
        at android.widget.ListView.fillSpecific(ListView.java:1504)
        ...

The app bug is on this line String name = trainers.get(position).name; inside the following class (Adapter) :

public class CustomGymTrainerAdapter extends ArrayAdapter<TrainerObject> implements Filterable {

    private static ArrayList<TrainerObject> trainers;
    private Activity context;

    public CustomGymTrainerAdapter(Activity _context, ArrayList<TrainerObject> _trainers) {
        super(_context, R.layout.notification_item, _trainers);
        this.context = _context;
        this.trainers = _trainers;
    }

    @Override
    public int getCount() {
        return trainers.size();
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        View r = convertView;
        CustomGymTrainerAdapter.ViewHolder viewHolder = null;
        if (r == null) {
            LayoutInflater layoutInflater = context.getLayoutInflater();
            r = layoutInflater.inflate(R.layout.gym_trainer_item, null);
            viewHolder = new CustomGymTrainerAdapter.ViewHolder(r);
            r.setTag(viewHolder);
        } else {
            viewHolder = (CustomGymTrainerAdapter.ViewHolder) r.getTag();
        }
        String name = trainers.get(position).name;
        String lastname = trainers.get(position).lastname;
        String email = trainers.get(position).email;

        viewHolder.tv_gym_trainer_name.setText(name);
        viewHolder.tv_gym_trainer_lastname.setText(lastname);
        viewHolder.tv_gym_trainer_email.setText(email);

        viewHolder.btn_gym_trainer_add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //TODO:
                //LOGICA AGGIUNTA TRAINER SCELTO TRA I PROPRI DIPENDENDTI
            }
        });
        return r;
    }

    class ViewHolder {
        TextView tv_gym_trainer_name, tv_gym_trainer_lastname, tv_gym_trainer_email;
        ImageView btn_gym_trainer_add;

        ViewHolder(View v) {
            tv_gym_trainer_name = v.findViewById(R.id.tv_gym_trainer_name);
            tv_gym_trainer_lastname = v.findViewById(R.id.tv_gym_trainer_lastname);
            tv_gym_trainer_email = v.findViewById(R.id.tv_gym_trainer_email);

            btn_gym_trainer_add = v.findViewById(R.id.btn_gym_trainer_add);
        }
    }

    @NonNull
    @Override
    public Filter getFilter() {
        Filter filter = new Filter() {

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults results = new FilterResults();
                ArrayList<TrainerObject> FilteredTrainers = new ArrayList<TrainerObject>();
                // perform your search here using the searchConstraint String.
                constraint = constraint.toString().toLowerCase();
                for (TrainerObject t : trainers) {
                    String dataNames = t.name;
                    if (dataNames.toLowerCase().startsWith(constraint.toString())) {
                        FilteredTrainers.add(t);
                    }
                }
                results.values = FilteredTrainers;
                results.count = FilteredTrainers.size();
                Log.e("VALUES", results.values.toString());

                return results;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                Log.e("TEST", results.values.toString());
                trainers = (ArrayList<TrainerObject>) results.values;
                notifyDataSetChanged();
            }


        };
        return filter;
    }
}

For completeness the class TrainerObject: (PS: I know the getter and setter methods are missing and that the variables should be private but it was for testing)

public class TrainerObject {
    public String user_id;
    public String name;
    public String lastname;
    public String email;
    public String qualification;
    public String fiscal_code;

    public TrainerObject(String user_id, String name, String lastname, String email, String qualification, String fiscal_code) {
        this.user_id = user_id;
        this.name = name;
        this.lastname = lastname;
        this.email = email;
        this.qualification = qualification;
        this.fiscal_code = fiscal_code;
    }

    @Override
    public String toString() {
        return "TrainerObject{" +
                "user_id='" + user_id + '\'' +
                ", name='" + name + '\'' +
                ", lastname='" + lastname + '\'' +
                ", email='" + email + '\'' +
                ", qualification='" + qualification + '\'' +
                ", fiscal_code='" + fiscal_code + '\'' +
                '}';
    }
}

The activity that calls the adapter is this one:

public class GymAddTrainerActivity extends AppCompatActivity {

    private int user_id;
    public static ArrayList<TrainerObject> trainers_list;
    static CustomGymTrainerAdapter trainer_adapter;
    ListView lv_trainer;
    EditText inputSearch;


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

        trainers_list = new ArrayList<TrainerObject>();

        //region CHECK INTENT EXTRAS
        Intent i = getIntent();
        if (!i.hasExtra("user_id")) {
            Toast.makeText(this, "User_id mancante", Toast.LENGTH_LONG).show();
            Intent new_i = new Intent(this, LoginActivity.class);
            startActivity(new_i);
        } else {
            user_id = i.getIntExtra("user_id", -1);
            Log.w("user_id ricevuto:", String.valueOf(user_id));
            if (user_id == -1) {
                Toast.makeText(this, "Utente non creato.", Toast.LENGTH_LONG).show();
                Intent new_i = new Intent(this, LoginActivity.class);
                startActivity(new_i);
            }
        }
        //endregion

        lv_trainer = (ListView) findViewById(R.id.lv_free_trainers);
        inputSearch = (EditText) findViewById(R.id.et_search_trainer);

        getTrainers();

        inputSearch.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
                // When user changed the Text
                GymAddTrainerActivity.this.trainer_adapter.getFilter().filter(cs);
            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
            }

            @Override
            public void afterTextChanged(Editable arg0) {
            }
        });
    }

    private void getTrainers() {
        GymAddTrainerActivity.ReceiveTrainersConn asyncTaskUser = (GymAddTrainerActivity.ReceiveTrainersConn) new GymAddTrainerActivity.ReceiveTrainersConn(new GymAddTrainerActivity.ReceiveTrainersConn.AsyncResponse() {
            @Override
            public void processFinish(ArrayList<TrainerObject> trainers) {
                trainers_list = trainers;
                if (trainers_list.size() > 0) {
                    //DATI RICEVUTI
                    runOnUiThread(new Runnable() {
                        public void run() {
                            //setto tramite l'adapter la lista dei trainer da visualizzare nella recycler view(notificationView)
                            trainer_adapter = new CustomGymTrainerAdapter(GymAddTrainerActivity.this, trainers_list);
                            lv_trainer.setAdapter(trainer_adapter);

                        }
                    });
                } else {
                    // NESSUN DATO RICEVUTO PERCHE' NESSUNA TRAINER LAVORA PER QUESTA PALESTRA
                    runOnUiThread(new Runnable() {
                        public void run() {
                            Toast.makeText(GymAddTrainerActivity.this, "Nessun personal triner disponibile", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
                //for (int j = 0; j < trainers_list.size(); j++) {
                //    Log.e("trainer n:" + j, trainers_list.get(j).toString());
                //}
            }

        }).execute(String.valueOf(user_id));
    }

    private static class ReceiveTrainersConn extends AsyncTask<String, String, JsonArray> {

        public interface AsyncResponse {
            void processFinish(ArrayList<TrainerObject> trainers);
        }

        public GymAddTrainerActivity.ReceiveTrainersConn.AsyncResponse delegate = null;

        public ReceiveTrainersConn(GymAddTrainerActivity.ReceiveTrainersConn.AsyncResponse delegate) {
            this.delegate = delegate;
        }

        @SuppressLint("WrongThread")
        @Override
        protected JsonArray doInBackground(String... params) {

            URL url;
            HttpURLConnection urlConnection = null;
            JsonArray _trainers = null;
            ArrayList<TrainerObject> t_objects = new ArrayList<TrainerObject>();

            try {
                url = new URL("http://10.0.2.2:4000/gym/get_new_trainers/" + params[0]);
                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("GET");
                urlConnection.setConnectTimeout(5000);
                urlConnection.connect();
                int responseCode = urlConnection.getResponseCode();
                urlConnection.disconnect();

                if (responseCode == HttpURLConnection.HTTP_OK) {

                    Log.e("Server response", "HTTP_OK");
                    String responseString = readStream(urlConnection.getInputStream());
                    _trainers = JsonParser.parseString(responseString).getAsJsonArray();

                    for (int i = 0; i < _trainers.size(); i++) {
                        JsonObject trainer = (JsonObject) _trainers.get(i);

                        String user_id = trainer.get("user_id").getAsString().trim();
                        String name = trainer.get("name").getAsString().trim();
                        String lastname = trainer.get("lastname").getAsString().trim();
                        String email = trainer.get("email").getAsString().trim();
                        String qualification = trainer.get("qualification").getAsString().trim();
                        String fiscal_code = trainer.get("fiscal_code").getAsString().trim();

                        TrainerObject t_obj = new TrainerObject(user_id, name, lastname, email, qualification, fiscal_code);
                        t_objects.add(t_obj);

                    }
                    //SE VA TUTTO A BUON FINE INVIO AL METODO procesFinish();
                    delegate.processFinish(t_objects);

                } else if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) {
                    Log.e("GET TRAINER", "response: HTTP_NOT_FOUND");
                    delegate.processFinish(new ArrayList<TrainerObject>());
                } else {
                    Log.e("GET TRAINER", "SERVER ERROR");
                }
            } catch (IOException e) {
                e.printStackTrace();
                Log.e("GET TRAINER", "I/O EXCEPTION ERROR");
            } finally {
                if (urlConnection != null)
                    urlConnection.disconnect();
            }
            return _trainers;
        }

        private String readStream(InputStream in) throws UnsupportedEncodingException {
            BufferedReader reader = null;
            StringBuffer response = new StringBuffer();
            try {
                reader = new BufferedReader(new InputStreamReader(in));
                String line = "";
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return response.toString();
        }
    }
}

Observation: both debug log return the correct value.

E/VALUES: [TrainerObject{user_id='9', name='nome', lastname='cognome', email='[email protected]', qualification='asd', fiscal_code='asd'}]
E/TEST: [TrainerObject{user_id='9', name='nome', lastname='cognome', email='[email protected]', qualification='asd', fiscal_code='asd'}]
0

There are 0 best solutions below