2011-09-02 18 views
7

Tengo una actividad con una ruleta, y me preguntaba si es posible cerrar la ruleta programáticamente, si el usuario la ha abierto.Android spinner cerrar

Toda la historia es que en el fondo estoy ejecutando un proceso en un hilo separado. Cuando el proceso ha terminado, invoco un controlador en la actividad principal y, dependiendo del resultado, realizo algunas tareas. Es entonces cuando quiero cerrar la ruleta, si el usuario la ha abierto.

La ruleta está en la disposición main.xml:

<Spinner android:id="@+id/birthPlaceSpinner" android:layout_weight="1" 
android:layout_height="wrap_content" android:prompt="@string/select" 
android:layout_width="fill_parent" /> 

y este es el Handler:

private class BirthplaceChangedHandler extends Handler { 

    @Override 
    public void handleMessage(Message msg) { 
     String placeFilterStr = birthPlaceFilterText.getText().toString(); 
     if ("".equals(placeFilterStr) || placeFilterStr == null || validNewAddresses.isEmpty()) { 
      birthPlaceSpinner.setEnabled(false); 
      hideGeoLocationInformation(); 
     } else { 
      birthPlaceSpinner.setEnabled(true); 
     } 
     adapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.multiline_spinner_dropdown_item, validNewAddressesStr) 
     birthPlaceSpinner.setAdapter(adapter); 
    } 
} 

Salud!

+0

Cómo estás creando/iniciar la ruleta? Lo que quiere hacer es casi seguro que es posible, pero no ha dado suficiente información para responder su pregunta. Los fragmentos de código ayudan. –

+0

Sobrescribir 'Spinner.onDetachedFromWindow', hacerlo público y llamar manualmente fue la única manera que funcionó para mí. Seguí http://stackoverflow.com/a/21122845/369317 –

Respuesta

7

No veo una manera de lograr eso - no hay ningún método en Spinner para cerrarlo. La parte "abierta" de Spinner es AlertDialog en Android 1.xy 2.x, y no estoy completamente seguro de cómo se implementa en Honeycomb cuando se utiliza el tema holográfico.

La única solución alternativa sería clonar el origen de Spinner y agregar un código usted mismo para cerrar el cuadro de diálogo. Pero, de nuevo, no funcionaría en Honeycomb o superior hasta que pueda ver y clonar ese código también.

Más allá de eso, creo que lo que quieres es un UX pobre. Si el usuario abrió el Spinner, lo más probable es que esté examinando activamente el contenido del Spinner y haciendo una selección. Sacar eso de debajo de sus dedos los confundirá, en el mejor de los casos. Por favor considere un enfoque alternativo.

Además, no use getApplicationContext() a menos que sepa por qué está usando getApplicationContext(). No necesita ni desea getApplicationContext() al crear un ArrayAdapter.

3

creo que debe desechar el uso de Spinner y en su lugar utilizar un ImageView con un Frame Animation (es decir <animation-list>) para crear su propio spinner. Usted acaba de configurar el fondo de ImageView para que sea su dibujo animado de cuadros.

Luego puede hacer fácilmente algo like this para iniciar y detenerlo.

1

¿Qué pasa con la clonación de una tecla 'atrás'?

Ok Acabo de intentar

[current activity].dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_BACK)); 

y no hicieron nada que pudiera ver - a continuación, pulsa la tecla RETRO física y la caída se redujo de distancia. También intenté hacer ACTION_UP justo después del down, sin efecto tampoco.

14

Esto funciona para mí:

class SomeAdapter extends BaseAdapter implements SpinnerAdapter { 
    //...... 
    public View getDropDownView(int position, View convertView, ViewGroup parent) { 
     View view = convertView; 
     if (view == null) { 
      //...... 
     } 
     view.setOnClickListener(new ItemOnClickListener(parent)); 
     return view; 
    } 
    //..... 
} 

y el detector de clics:

class ItemOnClickListener implements View.OnClickListener { 
    private View _parent; 

    public ItemOnClickListener(ViewGroup parent) { 
     _parent = parent; 
    } 

    @Override 
    public void onClick(View view) { 
     //....... 
     // close the dropdown 
     View root = _parent.getRootView(); 
     root.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK)); 
     root.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK)); 
    } 
} 
+0

¡Genial, gracias! – anthony

+0

Genial ... está funcionando. –

8

Bueno, es un poco complicado de lo que pensaba.

Aquí estoy agregando los detalles paso a paso aquí. Intenta seguirlo. Yo era capaz de lograr esto en el nivel API 10.

Y esta solución presupone que se supone que para cerrar el diálogo del sistema mediante programación cuando el usuario hace clic en el botón Inicio o Si tuviera que pasar a la siguiente actividad sin la interacción del usuario

El primer paso es crear un Spinner personalizado extendiendo Spinner Class. Digamos, he creado una clase llamada CustomSpinner en el paquete com.bts.sampleapp

Mi clase CustomSpinner se parece a esto,

package com.bts.sampleapp; 

import android.content.Context; 
import android.util.AttributeSet; 
import android.widget.Spinner; 

    public class CustomSpinner extends Spinner{ 
     Context context=null; 

     public CustomSpinner(Context context) { 
      super(context); 
      this.context=context; 
     } 

     public CustomSpinner(Context context, AttributeSet attrs, int defStyle) { 
      super(context, attrs, defStyle); 
     } 

     public CustomSpinner(Context context, AttributeSet attrs) { 
      super(context, attrs); 
     } 

     @Override 
     public void onDetachedFromWindow() { 
      super.onDetachedFromWindow(); 
     } 
    } 

Ahora en el archivo XML, cambie el elemento giratorio por esta spinner encargo,

 <com.bts.sampleapp.CustomSpinner 
     android:id="@+id/spin" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 

El siguiente paso es inicializar y configurar el adaptador a esta ruleta en su clase de actividad,

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    CustomSpinner spin=null; 
    spin=(CustomSpinner)findViewById(R.id.spin); 
    spin.setAdapter(spinnerAdapter); //you can set your adapter here. 
} 

El último paso es cerrar el cuadro de diálogo cuando el usuario hace clic en Inicio o cuando la Actividad se mueve al fondo. Para ello, sobreescribimos la onPause() como este,

@Override 
    protected void onPause() { 
     Log.i("Life Cycle", "onPause"); 
     spin.onDetachedFromWindow(); 
     super.onPause(); 
    } 

Ahora dentro del onPause() llama al método spin.onDetachedFromWindow(); el que hace el trabajo de cerrar el diálogo de consulta para usted.

Ahora que se dice, llamando al spin.onDetachedFromWindow(); desde cualquier lugar de su actividad debería ayudarlo a cerrar la ruleta programáticamente. Entonces, si esto es lo que quiere, elimine el onpause().

+0

¡El onDetachedFromWindow() funcionó para mí! ¡Gracias! –

-1

Utilice la clearFocus() para cerrar el spinner programitically

spinner.clearFocus(); 
1
public static void hideSpinnerDropDown(Spinner spinner) { 
    try { 
     Method method = Spinner.class.getDeclaredMethod("onDetachedFromWindow"); 
     method.setAccessible(true); 
     method.invoke(spinner); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
Cuestiones relacionadas