ArrayAdapter.getPosition(),找不到项:它在mOriginalValues中

时间:2014-04-30 23:27:33

标签: android search android-asynctask runtime-error android-arrayadapter

在我的班级中有各种AutoCompleteTextView,并且所有这些都与提示具有相同的ArrayAdapter。这个文本视图用于通过AsyncTask将数据发送到php页面,并在他的doInBackground方法中检查插入的值是适配器中包含的值之一(我不想要接受任何其他价值)。对于此检查,我只是这样做:

if(fermate.getPosition(fermata) < 0){
   return "lineaNonPresente";  // It is returned to onPostExecute
}

在此代码快照中,fermate是ArrayAdapter,fermata是不应在适配器中找到的字符串。如果找不到,我会返回String结尾doInBackground

有什么问题?问题是对象fermate。当我检查ArrayAdapter时,不再包含原始值,而只包含其中一些值。我通过在调试期间观察这个变量来看到它。进入fermate,有一个包含

的数组mObjets

[Via Roma - Cod: 2, San Rocco - Cod: 4, null, null, null, null, null, null, null, null, null, null]

和包含

的数组mOriginalValues

[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]

(应该进入fermate的所有元素)。

当我创建适配器时,mObject包含[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]mOriginalValues为空。

所以我的问题是两个:

  • 为什么AsyncTask ArrayAdapter中包含的值会发生变化?
  • 我如何制作方法getPosition()搜索mOriginalValues?或者这样做,数组mObjects不会受到不受控制的变化的影响?

我让全班的代码在这里帮助。

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;
    }
}

}

更新: 我试着在调用AsyncTask.execute()之前对onClickListener进行检查,我也遇到了同样的问题。代码的新部分是:

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();

                }


        }
    });

1 个答案:

答案 0 :(得分:1)

  

为什么在AsyncTask中包含ArrayAdapter中包含的值   改变?

因为你过滤了适配器(通过AutoCompleteTextView小部件),这使得它有一部分数据。

  

如何进行getPosition()搜索的方法   mOriginalValues?

你没有。该字段是私有的,因此您无法正常访问它(无论如何你都不应该这样做)。

  

或者这样做不会影响数组mObjects   不受控制的变化?

你接近这个错误的方式。 Arrayadapter有两个数据列表可以处理过滤:一个列表包含最初传递的数据集(这是必需的,因此您可以在过滤器重置后将适配器置于初始状态)和当前适配器当前所基于的数据列表(因此与适配器的任何交互都将考虑此列表)。您有两种选择:

  • 将数据(您在creaAdapter()方法中执行的操作)检索到列表中(而不仅仅是将项目直接添加到适配器中)并在片段中保留对该列表的引用(请记住如果它改变就更新它)。当您想要使用输入的值时,请根据您存储的列表引用检查该项,基本上是适配器在引擎盖下执行的操作:

    if(mAdapterDataListReference.indexOf(fermata) < 0){  // HERE THERE IS THE PIECE OF CODE
       return "lineaNonPresente"; 
    }
    
  • 扩展ArrayAdapter以添加您自己的列表参考。此引用将在适配器的构造函数中初始化,您还需要覆盖允许添加/删除add()addAll()clear()等数据的其他方法。然后,您还可以覆盖getItemPosition()以在您自己添加的数据列表参考中查找该项目。我不会选择这个,因为如果ArrayAdapter在其实施中使用getItemPosition(),你可能会搞砸了

此外,并且它们都具有与提示相同的ArrayAdapter。,我希望您没有使用与所有AutoCompleteTextView小部件相同的适配器实例(单个实例)你有。