在我的班级中有各种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();
}
}
});
答案 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
小部件相同的适配器实例(单个实例)你有。