2012-10-02 24 views
8

Estoy usando un adaptador personalizado con AutoCompleteTextView. Funciona bien en el emulador y mi tableta. Sin embargo, hay un problema en mi teléfono en modo horizontal. Las sugerencias automáticas completas que se muestran en este modo son información del objeto en lugar de texto. Sin embargo, cuando selecciono cualquier elemento, los campos se llenan correctamente con texto en los campos respectivos.Android AutoCompleteTextView muestra información del objeto en lugar de texto en modo horizontal

Auto Complete para otros campos que están basados ​​en Android Stock Array Adapter funciona bien.

¿Tengo que hacer algo por esto en mi Adaptador personalizado? Solo vi una pregunta similar en SO. Una respuesta para esa pregunta fue hablar sobre anular el método toString pero no pude entenderlo lo suficiente como para implementarlo en mi código.

Cualquier orientación será muy apreciada? Por favor, avíseme si necesita más información.

EDIT: Añadido mi código fuente adaptador personalizado ....

public class Part_Mstr_Info 
    { 
    private long part_id; 
    private String name, desg, org, dept; 

    public Part_Mstr_Info(long part_id, String name, String desg, String org, String dept) 
    { 
     this.part_id = part_id; 
     this.name = name; 
     this.desg = desg; 
     this.org = org; 
     this.dept = dept; 
    } 
    public long get_part_id() { return part_id; } 
    public String get_name() { return name; } 
    public String get_desg() { return desg; } 
    public String get_org() { return org; } 
    public String get_dept() { return dept; } 
} 

public class CustomAdapter extends ArrayAdapter<Part_Mstr_Info> implements Filterable{ 
    private List<Part_Mstr_Info> entries; 
    private ArrayList<Part_Mstr_Info> orig; 
    private Activity activity; 
    private ArrayFilter myFilter; 

    public CustomAdapter(Activity a, int textViewResourceId, ArrayList<Part_Mstr_Info> entries) { 
    super(a, textViewResourceId, entries); 
    this.entries = entries; 
    this.activity = a; 
} 

public static class ViewHolder{ 
    public TextView tv_ac_name; 
    public TextView tv_ac_desg; 
    public TextView tv_ac_org; 
    public TextView tv_ac_dept; 
} 

@Override 
public int getCount(){ 
     return entries!=null ? entries.size() : 0; 
} 

@Override 
public Part_Mstr_Info getItem(int index) { 
    return entries.get(index); 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View v = convertView; 
    ViewHolder holder; 
    if (v == null) { 
     LayoutInflater vi = 
      (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.ac_name_list, null); 
     holder = new ViewHolder(); 
     holder.tv_ac_name = (TextView) v.findViewById(R.id.ac_name); 
     holder.tv_ac_desg = (TextView) v.findViewById(R.id.ac_desg); 
     holder.tv_ac_org = (TextView) v.findViewById(R.id.ac_org); 
     holder.tv_ac_dept = (TextView) v.findViewById(R.id.ac_dept); 
     v.setTag(holder); 
    } 
    else 
     holder=(ViewHolder)v.getTag(); 

    final Part_Mstr_Info custom = entries.get(position); 
    if (custom != null) { 
     holder.tv_ac_name.setText(custom.get_name()); 
     holder.tv_ac_desg.setText(custom.get_desg()); 
     holder.tv_ac_org.setText(custom.get_org()); 
     holder.tv_ac_dept.setText(custom.get_dept()); 
    } 
    return v; 
} 

@Override 
public Filter getFilter() { 
    if (myFilter == null){ 
     myFilter = new ArrayFilter(); 
    } 
    return myFilter; 
} 

@Override 
public String toString() { 
    String temp = getClass().getName(); 
    return temp; 
} 

private class ArrayFilter extends Filter { 
    @Override 
    protected FilterResults performFiltering(CharSequence constraint) { 
     FilterResults results = new FilterResults(); 
     if (orig == null) 
      orig = new ArrayList<Part_Mstr_Info>(entries); 
     if (constraint != null && constraint.length() != 0) { 
      ArrayList<Part_Mstr_Info> resultsSuggestions = new ArrayList<Part_Mstr_Info>(); 
      for (int i = 0; i < orig.size(); i++) { 
       if(orig.get(i).get_name().toLowerCase().startsWith(constraint.toString().toLowerCase())){ 
        resultsSuggestions.add(orig.get(i)); 
       } 
      } 

      results.values = resultsSuggestions; 
      results.count = resultsSuggestions.size(); 

     } 
     else { 
      ArrayList <Part_Mstr_Info> list = new ArrayList <Part_Mstr_Info>(orig); 
      results.values = list; 
      results.count = list.size(); 
     } 
     return results; 
    } 

    @Override 
    @SuppressWarnings("unchecked") 
    protected void publishResults(CharSequence constraint, FilterResults results) { 
     clear(); 
     ArrayList<Part_Mstr_Info> newValues = (ArrayList<Part_Mstr_Info>) results.values; 
     if(newValues !=null) { 
      for (int i = 0; i < newValues.size(); i++) { 
       add(newValues.get(i)); 
      } 
      if(results.count>0) { 
       notifyDataSetChanged(); 
      } else { 
       notifyDataSetInvalidated(); 
      } 
     }  

    } 

} 

Respuesta

6

Sí, simplemente reemplazar el método toString() en su POJO.

public class MyObject { 
    ... 

    @Override 
    public String toString() { 
     return showThisStringOnAdapter; 
    } 
} 
+0

Intenté esto pero no funciona ... Probablemente porque estoy anulando los métodos filter y getview también ... Cuando intenté depurar, la ruta de ejecución no entra en el método toString en absoluto ... Añadiré más detalles y codifica mi pregunta original para aclarar ... – Sriman

+0

En base a lo que veo en la gama de aplicaciones ArrayAdapter, creo que tengo que hacer algo en el método getView pero no estoy seguro de lo que se debe hacer exactamente ... Como dije, funciona perfectamente en tabletas y emuladores. El problema solo está en el teléfono en modo horizontal cuando probablemente no hay suficiente espacio para mostrar la vista personalizada que tengo ... – Sriman

+0

Después de ver su CustomAdapter que no debería tener ningún problema, parece que la causa es 'ConfigChanges', ¿lo hizo? rotar el teléfono de vertical a horizontal? Si es así, mira [aquí] (http://stackoverflow.com/questions/456211/activity-restart-on-rotation-android), puede ayudarte – Aprian

3

Cree la clase personalizada que se extiende <AutoCompleteTextView />. Por ejemplo:

package lt.irisas.akcija.utils; 

import lt.irisas.akcija.data.ItemsModel; 
import android.content.Context; 
import android.database.Cursor; 
import android.util.AttributeSet; 
import android.widget.AutoCompleteTextView; 

/** Customizing AutoCompleteTextView to return Cursor column info as String 
*/ 
public class CustomAutoCompleteTextView extends AutoCompleteTextView { 

    public CustomAutoCompleteTextView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 
    /* Overriding this method and returning String type solves the problem */ 
    @Override 
    protected CharSequence convertSelectionToString(Object selectedItem) { 
     Cursor c = (Cursor) selectedItem; 

     return c.getString(c.getColumnIndex("COLUMN_NAME")); 
    } 
} 

Pero en lugar de <AutoCompleteTextView/> debe utilizar su costumbre uno. Por ejemplo:

<LinearLayout 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal" > 

     <lt.irisas.akcija.utils.CustomAutoCompleteTextView 
      android:id="@+id/search_field" 
      android:layout_width="0dip" 
      android:layout_height="wrap_content" 
      android:layout_weight="1" 
      android:singleLine="true" 
      android:imeOptions="actionSearch" > 
     </lt.irisas.akcija.utils.CustomAutoCompleteTextView> 
</LinearLayout> 

Espero que ayude. Bueno, al menos lo hizo por mí.

+0

No funciona para mí ... La razón es que tengo que devolver un objeto de la clase Part_Mstr_Info para que pueda obtener el nombre, desg, org y departamento de él. Mis sugerencias automáticas son dos líneas, cada una con el nombre en el primero y los otros tres campos en el segundo ... Así que no puedo devolver una cadena ... Necesito devolver el objeto completo ... – Sriman

0

He encontrado la respuesta la última vez. Tuve el mismo problema y parece que la función de autocompletar usa el método convertToString() en modo horizontal en lugar del método newView() y bindView(). Debe devolver todos los datos de su cursor en una sola cadena sin "\ n", como si los elementos se visualizaran horizontales sobre el teclado.

ejemplo en su AutoCompleteTextViewAdapter, añadir el método:

 @Override 
    public CharSequence convertToString(Cursor cursor) { 


     String name = cursor.getString(0); 
     String number = cursor.getString(1); 


     return name+" : "+number; 
    } 

he comprobado con mi teléfono Xperia U y otro Galaxy Note y funciona. Es así de simple. Por supuesto, rellenará este método dependiendo de lo que quiera que se muestre.

+0

Gracias ... Lo haré intente esto en unos días e informe lo que sucede ... – Sriman

0

Ésta es su respuesta:

adapter.setCursorToStringConverter(new CursorToStringConverter() { 
    @Override 
    public CharSequence convertToString(Cursor c) { 
     return c.getString(c.getColumnIndexOrThrow("Column")); 
    } 
}); 
10

La forma correcta de hacerlo es reemplazar el método Filter#convertResultToString(Object) en su clase privada ArrayFilter.

Como se ha dicho en la documentación de Android

pública CharSequence convertResultToString (resultValue Objeto)

convierte un valor de la con filtro en un CharSequence. Las subclases deben anular este método para convertir sus resultados. La implementación predeterminada devuelve una cadena vacía para los valores nulos o la representación de cadena predeterminada del valor.

En su caso, debería ser algo así:

private class ArrayFilter extends Filter { 
    @Override 
    public CharSequence convertResultToString(Object resultValue) { 
     return ((Part_Mstr_Info) resultValue).get_name(); 
    } 

La adición de este método permitirá que el AutoCompleteTextView para proporcionar corrige consejos (en la vista horizontal) en lugar de referencias a objetos o toString predeterminado

Cuestiones relacionadas