programacion - manual de android en pdf
Cómo ocultar un elemento en un Android Spinner (7)
Creo que será mejor poner validación en la lista de arreglos en lugar de hacerlo en Spinner porque una vez que se filtra el elemento, será seguro agregarlo en Spinner.
Estoy buscando una forma de ocultar un elemento en un widget de giro de Android. Esto le permitiría simular un spinner sin elementos seleccionados, y asegura que se llame siempre a onItemSelected () para cada elemento seleccionado (si el elemento oculto es el "actual"). Normalmente, siempre hay un elemento en la ruleta que no genera una devolución de llamada, es decir, la actual.
Hay algún código en stackoverflow sobre cómo desactivar elementos (grises), pero no cómo ocultar ítems completamente como si no existieran.
Después de mucha experimentación, he encontrado una solución un tanto hack-ish que funciona en varias plataformas Android antiguas y nuevas. Tiene algunos inconvenientes cosméticos menores que son difíciles de notar. Todavía me gustaría saber de una solución más oficial, aparte de "no hagas eso con un girador".
Esto siempre oculta el primer elemento en la ruleta, pero podría extenderse con bastante facilidad para ocultar un elemento arbitrario o más de un elemento. Agregue un ítem ficticio que contenga una cadena vacía al comienzo de su lista de ítems giratorios. Es posible que desee establecer la selección actual del control giratorio en el elemento 0 antes de que se abra el cuadro giratorio, esto simulará un control giratorio no seleccionado.
Ejemplo de configuración de Spinner con anulación del método ArrayAdapter:
List<String> list = new ArrayList<String>();
list.add(""); // Initial dummy entry
list.add("string1");
list.add("string2");
list.add("string3");
// Populate the spinner using a customized ArrayAdapter that hides the first (dummy) entry
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, list) {
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent)
{
View v = null;
// If this is the initial dummy entry, make it hidden
if (position == 0) {
TextView tv = new TextView(getContext());
tv.setHeight(0);
tv.setVisibility(View.GONE);
v = tv;
}
else {
// Pass convertView as null to prevent reuse of special case views
v = super.getDropDownView(position, null, parent);
}
// Hide scroll bar because it appears sometimes unnecessarily, this does not prevent scrolling
parent.setVerticalScrollBarEnabled(false);
return v;
}
};
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mySpinner.setAdapter(dataAdapter);
Encontré esta solución que resolvió mi problema.
final Spinner mySpinner = (Spinner)findViewById(R.id.spinner_triptype);
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.spinner_item, R.id.weekofday, triptype_initial);
final ArrayAdapter<String> adapter_temp = new ArrayAdapter<String>
(this,R.layout.spinner_item, R.id.weekofday, triptype_array);
mySpinner.setAdapter(adapter);
mySpinner.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// display your error popup here
if(flag_spinner_isFirst){
mySpinner.setAdapter(adapter_temp);
flag_spinner_isFirst = false;
}
v.onTouchEvent(event);
return true;
}
});
Es más fácil ocultar un elemento al final de la lista al truncar la lista.
Pero primero debe seleccionarlo para que aparezca en la rueda giratoria, y luego verificar si la selección ha sido cambiada a uno de los elementos mostrados.
List<String> list = new ArrayList<String>();
list.add("string1");
list.add("string2");
list.add("string3");
list.add("[Select one]");
final int listsize = list.size() - 1;
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, list) {
@Override
public int getCount() {
return(listsize); // Truncate the list
}
};
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mySpinner.setAdapter(dataAdapter);
mySpinner.setSelection(listsize); // Hidden item to appear in the spinner
Otro enfoque que funcionó mejor para mí es devolver un nuevo objeto de vista en blanco. Este es un enfoque considerablemente limpio ya que no está jugando con elementos de matriz.
Crea tu clase de adaptador extendiendo ArrayAdapter
dentro de tu método
public View getView(int position, View convertView, ViewGroup parent) {
View row = getCustomView();
if(position==0) // put the desired check here.
{
row = new View(context);
}
}
return row;
}
Para ocultar cualquier elemento en el menú desplegable de la rueda giratoria, debe pasar la posición del elemento que debe ocultarse según los criterios requeridos. Lo he logrado en un caso de uso de ocultar el elemento que se selecciona de la lista desplegable
public class CustomAdapter extends ArrayAdapter<String> {
private List<String> dates;
private int hideItemPostion;
public CustomAdapter (Context context, int resource, List<String> dates) {
super(context, resource,dates);
this.dates=dates;
}
public void setItemToHide(int itemToHide)
{
this.hideItemPostion =itemToHide;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
View v = null;
if (position == hideItemPostion) {
TextView tv = new TextView(getContext());
tv.setVisibility(View.GONE);
tv.setHeight(0);
v = tv;
v.setVisibility(View.GONE);
}
else
v = super.getDropDownView(position, null, parent);
return v;
}}
Y configurar el adaptador es algo como esto
final CustomAdapter dataAdapter = new CustomAdapter(this,R.layout.spinner_item,dates);
dataAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
spinner.setAdapter(dataAdapter);
dataAdapter.setItemToHide(0);
Al seleccionar algunos elementos del menú desplegable también debe cambiarse la posición
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, final int i, long l) {
dataAdapter.notifyDataSetChanged();
mEPGDateSelector.setSelection(i);
dataAdapter.setItemToHide(i);}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
Para ocultar un elemento arbitrario o más de un elemento, creo que puede implementar su propio adaptador y establecer el índice (o lista de matrices) del índice que desea ocultar.
public class CustomAdapter extends ArrayAdapter<String> {
private int hidingItemIndex;
public CustomAdapter(Context context, int textViewResourceId, String[] objects, int hidingItemIndex) {
super(context, textViewResourceId, objects);
this.hidingItemIndex = hidingItemIndex;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
View v = null;
if (position == hidingItemIndex) {
TextView tv = new TextView(getContext());
tv.setVisibility(View.GONE);
v = tv;
} else {
v = super.getDropDownView(position, null, parent);
}
return v;
}
}
Y use su adaptador personalizado cuando cree la lista de elementos.
List<String> list = new ArrayList<String>();
list.add(""); // Initial dummy entry
list.add("string1");
list.add("string2");
list.add("string3");
int hidingItemIndex = 0;
CustomAdapter dataAdapter = new CustomAdapter(this, android.R.layout.simple_spinner_item, list, hidingItemIndex);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mySpinner.setAdapter(dataAdapter);
(No he probado el código) espero que ayude.
Solo por interés, hice una solución para usar "Preguntar" como una pista. Este código está hecho para Xamarin.Android
, pero podría estar perfectamente portado a Java en 10 minutos. Úselo como un ArrayAdapter
simple sin agregar 0 elementos indexados o indexados por conteo a la matriz de origen. También establece SpinnerGeolocation.SelectedItemId
en -1 cuando no se elige nada (la hint
es el elemento actual).
public class ArrayAdapterWithHint<T>: ArrayAdapter<T>
{
protected bool HintIsSet = false;
protected int HintResource = 0;
public ArrayAdapterWithHint(Context context, int textViewResourceId,
T[] objects)
: base(context, textViewResourceId, objects)
{
}
public ArrayAdapterWithHint(Context context, int hintResource,
int textViewResourceId, T[] objects)
: base(context, textViewResourceId, objects)
{
HintResource = hintResource;
}
public ArrayAdapterWithHint(Context context, int textViewResourceId,
IList<T> objects)
: base(context, textViewResourceId, objects)
{
}
public ArrayAdapterWithHint(Context context, int hintResource,
int textViewResourceId, IList<T> objects)
: base(context, textViewResourceId, objects)
{
HintResource = hintResource;
}
public override View GetDropDownView(int position, View convertView,
ViewGroup parent)
{
if (HintIsSet)
return base.GetDropDownView(position + 1,
convertView, parent);
return base.GetDropDownView(position, convertView, parent);
}
public override View GetView(int position, View convertView,
ViewGroup parent)
{
if (!HintIsSet && parent is Spinner &&
!string.IsNullOrWhiteSpace((parent as Spinner).Prompt))
{
Insert((parent as Spinner).Prompt, 0);
HintIsSet = true;
(parent as Spinner).SetSelection(base.Count - 1);
}
if (HintIsSet && position >= base.Count - 1)
{
View hintView = base.GetView(0, convertView, parent);
if (hintView is TextView)
(hintView as TextView).SetTextAppearance(
Context, HintResource);
return hintView;
}
if (HintIsSet && position < base.Count - 1)
return base.GetView(position + 1, convertView, parent);
return base.GetView(position, convertView, parent);
}
public override long GetItemId(int position)
{
if (HintIsSet)
{
if (position >= base.Count - 1)
return -1;
return position;
}
return base.GetItemId(position);
}
public override int Count
{
get
{
return base.Count > 0 && HintIsSet ? base.Count - 1 : base.Count;
}
}
}