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'}]