2011-03-30 18 views
16

Implementé un TabActivity que implementa el OnTabChangeListener. La actividad se notificará en los cambios de pestaña (onTabChanged(String tabId)).Recibir una notificación cuando se selecciona la pestaña actual nuevamente

¿También es posible recibir notificaciones si el usuario selecciona la pestaña actual nuevamente?

Me gustaría utilizar este evento para realizar una "actualización" del contenido de la pestaña actual en lugar de proporcionar un botón de actualización en la pestaña o en el menú de opciones.


Esa es la forma que finalmente resuelto el problema - solución pista estaba en MisterSquonk respuesta.

(1) Defina un OnTabReselectListener que debe ser implementado por una actividad que represente un contenido de pestañas y que será notificado en eventos de reselección.

/** 
* Interface definition for a callback to be invoked when a current selected tab 
* in a TabHost is selected again. 
*/ 
public interface OnTabReselectListener { 

    /** 
    * Called when a current visible tab is selected again. Will not be invoked 
    * on tab changes. 
    */ 
    void onTabReselect(); 

} 

(2) setOnTouchListener para cada niño TabWidget en onCreate() de la TabActivity (de la respuesta de MisterSquonk)

for (int i = 0; i < tabWidget.getChildCount(); i++) { 
    View v = tabWidget.getChildAt(i); 
    v.setOnTouchListener(this); 
} 

(3) Implementar OnTouchListener.onTouch() en la TabActivity. Haga un poco de lógica para decidir si la pestaña actual fue seleccionada nuevamente y notifique la actividad de la pestaña.

/** 
* @see android.view.View.OnTouchListener#onTouch(android.view.View, 
*  android.view.MotionEvent) 
*/ 
@Override 
public boolean onTouch(View v, MotionEvent event) { 
    boolean consumed = false; 
    // use getTabHost().getCurrentTabView to decide if the current tab is 
    // touched again 
    if (event.getAction() == MotionEvent.ACTION_DOWN 
      && v.equals(getTabHost().getCurrentTabView())) { 
     // use getTabHost().getCurrentView() to get a handle to the view 
     // which is displayed in the tab - and to get this views context 
     View currentView = getTabHost().getCurrentView(); 
     Context currentViewContext = currentView.getContext(); 
     if (currentViewContext instanceof OnTabReselectListener) { 
      OnTabReselectListener listener = (OnTabReselectListener) currentViewContext; 
      listener.onTabReselect(); 
      consumed = true; 
     } 
    } 
    return consumed; 
} 
+0

¿Qué está utilizando para establecer como indicador de las pestañas? – Squonk

+0

@MisterSquonk Estoy usando una cadena. Ver mi edición – FrVaBe

+0

Ver mi respuesta para un posible ángulo para explorar. – Squonk

Respuesta

9

Usted puede ser capaz de conseguir que esto funcione por tener su TabActivity implementar View.onTouchListener y llamando setOnTouchListener para cada una de las pestañas ...

for (int i = 0; i < tabWidget.getChildCount(); i++) { 
    View v = tabWidget.getChildAt(i); 
    v.setOnTouchListener(this); 
} 

Entonces anular onTouch() en su actividad ...

@Override 
public boolean onTouch(View v, MotionEvent event) { 

    // Not sure what to do here to identify each tab 

    return false; 
} 

Como se puede ver en el comentario en el abov e, no estoy seguro de qué hacer con el parámetro View (v) en el oyente onTouch para identificar qué pestaña se ha tocado.

Puedo confirmar que se activa al tocar o no la pestaña actualmente seleccionada o una que no está seleccionada y no interfiere con el cambio de pestañas.

Espero que ayude.

+0

Gracias por esta posibilidad de solución. Funcionó para mí Agrego la forma en que finalmente lo hice a mi pregunta (ya que no tengo permiso para editar su respuesta). – FrVaBe

+2

Su solución funciona para mí, gracias – Dharmendra

+0

, consulte el siguiente enlace, http://stackoverflow.com/questions/9372851/how-to-detecting-a-click-on-an-already-selected-tab-button/ 17876162 # 17876162 –

1

No, es más bien imposible. A continuación se muestra el código de TabHost

public void setCurrentTab(int index) { 
    if (index < 0 || index >= mTabSpecs.size()) { 
     return; 
    } 

    if (index == mCurrentTab) { 
     return; 
    } 
    ... 

Usted no tiene acceso a mCurrentTab, por lo que el oyente no es ni siquiera invocado.

Pero si realmente quiere puede probar la reflexión (Change private static final field using Java reflection por ejemplo)

+1

Esta es una sugerencia útil para ver el código de TabHost. Intenté extender un 'CustomTabHost' que notificará un' CustomOnTabSelectListener' pero ahora parece difícil hacer que TabActivity use este TabHost personalizado, y no quiero hacer demasiadas cosas 'Custom' ... +1 para el momento (aceptará su respuesta si no hay nadie arriba) – FrVaBe

4

Soy algo nuevo en Android, pero creo que tengo una mejor solución para este problema.

En primer lugar (como se dijo anteriormente) este código en TabHost.Java hace que sea imposible esperar un segundo clic en un botón de pestaña:

public void setCurrentTab(int index) { 
if (index < 0 || index >= mTabSpecs.size()) { 
    return; 
} 

if (index == mCurrentTab) { 
    return; 
} 
... 

así que empieza con la creación de su propia subclase de TabHost (com.mydomain.CustomTabHost)

@Override 
public void setCurrentTab(int index) { 
if (this.getCurrentTab() == index) { 
     // User clicked active tab... 
    } 
    super.setCurrentTab(index); 
} 

Su tabActivity está buscando un componente TabHost con el id "tabhost". Así que basta con cambiar la referencia en su diseño-XML desde TabHost a su nueva clase personalizada:

<com.yourdomain.CustomTabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent">

(Note el atributo android: id)

/Tommy

+0

+1 para esta solución alternativa: no se verificó en detalle, pero debería funcionar. – FrVaBe

0

En especial trabajo en 2.2 y use ActivityGroup para agrupar actividades ya que los Fragmentos se introducen en API 11. Entonces, no sé sobre Fragmentos, pero si está trabajando con ActivityGroup, esto funciona para mí:

Primero, Felicitaciones a MisterSquonk por su "uso de la idea de interfaz OnTouchListener !!"

1) Haga su TabHost estático, es decir, static TabHost tabhost. En su ActivityGroup, tome una variable de clase static de la misma clase (ActivityGroup) como static YourActivityGroup activitygroup; e inicialice en onCreate con this y cree un método que cambie la vista y la actividad dentro de la misma pestaña. como:

public void replaceContentView(String activityIdOrTag,Intent activityIntent) 
    {     
     View v= getLocalActivityManager().startActivity(activityIdOrTag,activityIntent) 
        .getDecorView(); 
    this.setContentView(v); 
} 

2) Basta con aplicar OnTouchListener a cualquiera de sus actividades, que se incluye en su ActivityGroup o yo recomiendo, implementar para su ActivityGroup.

3) Establecer un OnTouchListener como

YourTabActivity.tabhost.getCurrentTabView().setOnTouchListener(this)

4) Ahora en OnTouch(View v,MotionEvent e):

if (e.getAction()==MotionEvent.ACTION_DOWN) 
    { 
    Intent backToTop = new Intent(this, YourTopLevel.class); 
    YourActivityGroup.activitygroup.replaceContentView("YourTopActivity", backToTop); 
    } 

la esperanza que esto le ayuda. Soy nuevo en Android. Cualquier pregunta será muy apreciada.

+0

Gracias por esta solución alternativa. Lamentablemente, no puedo verificarlo en este momento. Si a alguien le "gusta", ¡debería sentirse libre de votar! – FrVaBe

Cuestiones relacionadas