Reputation: 607
In my class there are various AutoCompleteTextView
, and all of them have the same ArrayAdapter
as hints. This text views are used to sent data to a php page through an AsyncTask
, and in his doInBackground
method I check that the value inserted is one of the value contained into the adapter(I don't want to accept any other value). For this check I simply do:
if(fermate.getPosition(fermata) < 0){
return "lineaNonPresente"; // It is returned to onPostExecute
}
In this snap of code, fermate
is the ArrayAdapter, and fermata
is the string that should not be found into the adapter. If otherwise it is found, I return a String
ending doInBackground
.
What is the problem? The problem is the object fermate
. When I check the ArrayAdapter
does not contain no more the original values, but just some of them. I saw it by watching this variable during the debug. Into fermate
there is an array mObjets
that contains
[Via Roma - Cod: 2, San Rocco - Cod: 4, null, null, null, null, null, null, null, null, null, null]
and an array mOriginalValues
that contains
[Piazza Torino - Cod: 1, Via Roma - Cod: 2, Corso Nizza - Cod: 3, San Rocco - Cod: 4, Crocetta - Cod: 5, Provincia - Cod: 6, Municipio - Cod: 7, Piazzale Serenella - Cod: 9, FermataLocale - Cod: 16, Mi Serve - Cod: 17]
(all the element that should be into fermate
).
When I create the adapter, mObject contains [Piazza Torino - Cod: 1, Via Roma - Cod: 2, Corso Nizza - Cod: 3, San Rocco - Cod: 4, Crocetta - Cod: 5, Provincia - Cod: 6, Municipio - Cod: 7, Piazzale Serenella - Cod: 9, FermataLocale - Cod: 16, Mi Serve - Cod: 17]
and mOriginalValues
is null.
So my questions are two:
AsyncTask
the values contained into the ArrayAdapter
change?getPosition()
searches into mOriginalValues
? Or doing so that the array mObjects
will not be affected from uncontrolled changes?I let the code of the whole class here to help.
package com.example.app.Fragment;
imports [...]
public class FragmentAggiungiLinea extends Fragment {
private Context context;
private LayoutInflater li;
private Button btnNuovaFermata;
private Button btnEliminaFermata;
private Button btnConfermaLinea;
private AutoCompleteTextView primaFermata;
private EditText edtNomeLinea;
private EditText edtCodiceLinea;
private LinearLayout layoutBase;
private ArrayAdapter<String> fermate;
@SuppressWarnings("unused")
private static final String TAG = FragmentAggiungiLinea.class.getSimpleName();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_aggiungi_linea, container, false); }
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
context = getActivity();
li = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
btnEliminaFermata = (Button) getView().findViewById(R.id.btnEliminaFermata);
btnNuovaFermata = (Button) getView().findViewById(R.id.btnNuovaFermata);
btnConfermaLinea = (Button) getView().findViewById(R.id.btnConfermaLinea);
layoutBase = (LinearLayout) getView().findViewById(R.id.layoutBase);
primaFermata = (AutoCompleteTextView) getView().findViewById(R.id.edtPrimaFermata);
edtNomeLinea = (EditText) getView().findViewById(R.id.edtNomeLinea);
edtCodiceLinea = (EditText) getView().findViewById(R.id.edtCodiceLinea);
fermate = new ArrayAdapter<String>(context,android.R.layout.simple_dropdown_item_1line);
creaAdapter();
primaFermata.setAdapter(fermate);
btnNuovaFermata.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(!((EditText)((LinearLayout) layoutBase.getChildAt(layoutBase.getChildCount() - 1)).getChildAt(1)).getText().toString().matches("")){
LinearLayout nuovoLayout = (LinearLayout) li.inflate(R.layout.nuova_fermata_intermedia, null);
// I get the new EditText and I put the adapter.
AutoCompleteTextView nuovaFermata = (AutoCompleteTextView) nuovoLayout.getChildAt(1);
nuovaFermata.setAdapter(fermate);
layoutBase.addView(nuovoLayout);
btnEliminaFermata.setEnabled(true);
}else{
Toast.makeText(context, "Completare prima l'ultima fermata", Toast.LENGTH_SHORT).show();
}
}
});
btnEliminaFermata.setEnabled(false);
btnEliminaFermata.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
layoutBase.removeViewAt(layoutBase.getChildCount() - 1);
if(layoutBase.getChildCount() == 1) btnEliminaFermata.setEnabled(false);
}
});
btnConfermaLinea.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(!edtCodiceLinea.getText().toString().matches(""))
if(!edtNomeLinea.getText().toString().matches(""))
new UploadLinea().execute();
}
});
}
private void creaAdapter(){
// I create an adapter with the stops.
fermate.clear();
// I get the local database.
DatabaseLocale db = new DatabaseLocale(context);
SQLiteDatabase dbLeggibile = db.getReadableDatabase();
String[] colonne = {DatabaseLocale.getTagCodiceFermata(), DatabaseLocale.getTagNomeFermata()};
String tabella = DatabaseLocale.getTableNameFermata();
Cursor cursore = dbLeggibile.query(tabella, colonne, null, null, null, null, null);
while(cursore.moveToNext()){
fermate.add(cursore.getString(1) + " - Cod: " + cursore.getString(0));
}
cursore.close();
db.close();
}
class UploadLinea extends AsyncTask<Void, Void, String>{
private ProgressDialog pDialog;
@SuppressWarnings("unused")
private final String TAG = UploadLinea.class.getSimpleName();
private String NUOVA_LINEA;
List<NameValuePair> params = null;
JSONObject json = null;
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(context);
pDialog.setMessage("Caricamento linea...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
NUOVA_LINEA = GlobalClass.getDominio() + "Upload/caricaLinea.php";
}
protected String doInBackground(Void... voids) {
String valoreRitornato = null;
JSONParser jsonParser = new JSONParser();
try {
params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("NomeLinea", edtNomeLinea.getText().toString()));
params.add(new BasicNameValuePair("CodLinea", edtCodiceLinea.getText().toString()));
int indice = 0;
while(indice < layoutBase.getChildCount()){
LinearLayout layoutFermata = (LinearLayout) layoutBase.getChildAt(indice);
String fermata = ((AutoCompleteTextView) layoutFermata.getChildAt(1)).getText().toString();
if(fermate.getPosition(fermata) < 0){ // HERE THERE IS THE PIECE OF CODE
return "lineaNonPresente";
}
if(trovatoInArrayList(fermata.split(" - Cod: ")[1])){
return "giaPresente";
}
params.add(new BasicNameValuePair("Fermate[]", fermata.split(" - Cod: ")[1]));
indice++;
}
// Request to the .php page.
json = jsonParser.makeHttpRequest(
NUOVA_LINEA, "POST", params);
valoreRitornato = json.getString(GlobalClass.getTagMessage());
} catch (JSONException e) {
Log.e(TAG, "Error " + e.toString());
}
return valoreRitornato;
}
@Override
protected void onPostExecute(String valoreRitornato) {
super.onPostExecute(valoreRitornato);
pDialog.dismiss();
if(valoreRitornato == "giaPresente"){
valoreRitornato = "Ogni fermata può essere inserita una volta soltanto.";
} else if(valoreRitornato == "lineaNonPresente"){
valoreRitornato = "Le linee devono avere uno dei valori suggeriti.";
}else{
try {
if(json.getInt(GlobalClass.getTagSuccess()) != 0){
DatabaseLocale db = new DatabaseLocale(context);
SQLiteDatabase dbScrivibile = db.getWritableDatabase();
ContentValues valori = new ContentValues();
valori.put(DatabaseLocale.getTagCodiceLinea(), edtCodiceLinea.getText().toString());
valori.put(DatabaseLocale.getTagNomeLinea(), edtNomeLinea.getText().toString());
valori.put(DatabaseLocale.getTagCodiceCapolinea(),
((AutoCompleteTextView)((LinearLayout) layoutBase.getChildAt(0)).getChildAt(1)).getText().toString().split(" - Cod: ")[1]);
dbScrivibile.insert(DatabaseLocale.getTableNameLinea(), null, valori);
for (int i = 0; i < params.size(); i++) {
BasicNameValuePair valore = ((BasicNameValuePair) params.get(i));
if(valore.getName() == "Fermate[]" && i != (params.size() - 1)){
valori = new ContentValues();
valori.put(DatabaseLocale.getTagCodiceLinea(), edtCodiceLinea.getText().toString());
valori.put(DatabaseLocale.getTagCodiceFermata(), valore.getValue());
valori.put(DatabaseLocale.getTagSuccessiva(), ((BasicNameValuePair) params.get(i + 1)).getValue());
}else if(i == (params.size() - 1)){
valori = new ContentValues();
valori.put(DatabaseLocale.getTagCodiceLinea(), edtCodiceLinea.getText().toString());
valori.put(DatabaseLocale.getTagCodiceFermata(), valore.getValue());
valori.put(DatabaseLocale.getTagSuccessiva(), 0);
}
dbScrivibile.insert(DatabaseLocale.getTableNameTratta(), null, valori);
}
dbScrivibile.close();
db.close();
}
} catch (JSONException e) {
Log.e(TAG, "Error " + e.toString());
}
while(layoutBase.getChildCount() > 1) layoutBase.removeViewAt(layoutBase.getChildCount() - 1);
primaFermata.setText("");
edtCodiceLinea.setText("");
edtNomeLinea.setText("");
}
Toast.makeText(context, valoreRitornato, Toast.LENGTH_LONG).show();
Log.d(TAG, valoreRitornato);
}
private boolean trovatoInArrayList(String s){
for (NameValuePair elemento : params) {
if(elemento.getValue() == s) return true;
}
return false;
}
}
}
UPDATE: I tryed to do the checks into the onClickListener before to call AsyncTask.execute(), and I get the same problem. The new part of code is this:
btnConfermaLinea.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(!edtCodiceLinea.getText().toString().matches(""))
if(!edtNomeLinea.getText().toString().matches("")){
// Creo qui i parametri per risolvere il problema:
// http://stackoverflow.com/questions/23399793/arrayadapter-getposition-item-not-found-it-is-in-moriginalvalues
// (non ho ancora ricevuto risposte).
params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("NomeLinea", edtNomeLinea.getText().toString()));
params.add(new BasicNameValuePair("CodLinea", edtCodiceLinea.getText().toString()));
int indice;
for(indice = 0; indice < layoutBase.getChildCount(); indice++){
LinearLayout layoutFermata = (LinearLayout) layoutBase.getChildAt(indice);
String fermata = ((AutoCompleteTextView) layoutFermata.getChildAt(1)).getText().toString();
if(trovatoInArrayList(fermata.split(" - Cod: ")[1])){
Toast.makeText(context, "Ogni fermata può essere inserita una volta soltanto.", Toast.LENGTH_LONG).show();
break;
}
if(fermate.getPosition(fermata) < 0){
Toast.makeText(context, "Le linee devono avere uno dei valori suggeriti.", Toast.LENGTH_LONG).show();
break;
}
params.add(new BasicNameValuePair("Fermate[]", fermata.split(" - Cod: ")[1]));
}if(indice == layoutBase.getChildCount())
new UploadLinea().execute();
}
}
});
Upvotes: 0
Views: 2863
Reputation: 87064
Why in the AsyncTask the values contained into the ArrayAdapter change?
Because you filter the adapter(through the AutoCompleteTextView
widget) which makes it have a subset of the data.
How can I make so that the method getPosition() searches into mOriginalValues?
You don't. That field is made private so you can't normally access it(and you shouldn't anyway).
Or doing so that the array mObjects will not be affected from uncontrolled changes?
You're approaching this the wrong way. The Arrayadapter
has two lists of data to be able to handle the filtering: one list containing the initially passed set of data(this is required so you can bring the adapter to the initial state after a filter reset) and the current list of data on which the adapter is currently based(so any interaction with the adapter will take this list in consideration). You have two options:
retrieve the data(what you do in the creaAdapter()
method) into a list(and not just add the items directly to the adapter) and keep a reference to that list in your fragment(remember to update it if it changes). When you want to use the value entered check that item against the list reference that you stored, basically what the adapter does under the hood:
if(mAdapterDataListReference.indexOf(fermata) < 0){ // HERE THERE IS THE PIECE OF CODE
return "lineaNonPresente";
}
extend the ArrayAdapter
to add your own list reference. This reference will be initialized in the adapter's constructor, you'll also need to override the other methods that allow adding/deleting data like add()
, addAll()
, clear()
. Then you also override the getItemPosition()
to look for the item in your own added data list reference. I wouldn't choose this because if the ArrayAdapter
uses the getItemPosition()
in its implementation you could mess things up
Also, and all of them have the same ArrayAdapter as hints., I hope you're not using the same adapter instance(a single instance) with all the AutoCompleteTextView
widgets that you have.
Upvotes: 1