2011-03-22 23 views
17

Tengo un TabHost con dos actividades para niños en él (en dos pestañas). También implementé una función pública en una de estas actividades a la que me gustaría llamar desde mi padre (TabHost), para activar alguna acción dentro de la pestaña.¿Cómo hacer referencia a la actividad infantil de TabHost para llamar a una función pública?

¿Es posible hacer referencia a la actividad desde el TabHost para llamar a una función pública?

Gracias

aquí es mi configuración tabhost:

res = getResources(); 
    tabHost = getTabHost(); 

    TabHost.TabSpec spec; 
    Intent intent; 

    intent = new Intent().setClass(this, home.class); 
    spec = tabHost.newTabSpec("home").setIndicator("Groups", res.getDrawable(R.drawable.groups)).setContent(intent); 
    tabHost.addTab(spec); 
    intent = new Intent().setClass(this, messages.class); 
    spec = tabHost.newTabSpec("messages").setIndicator("Messages", res.getDrawable(R.drawable.messages)).setContent(intent);  
    tabHost.addTab(spec); 

Respuesta

22

Mi enfoque sería definir una clase anidada 'oyente' en la actividad infantil que se extiende BroadcastReceiver.

Simplemente transmitiría un Intento desde mi TabActivity que dispararía el BroadcastReceiver para realizar la acción.

EDIT: Para dar ejemplo de código ...

Los pasos son ...

  1. Definir el filtro de intención en el manifiesto
  2. Añadir al anidada 'oyente' para el niño actividad
  3. Establecer onResume()/onPause() en actividad secundaria para registrar/anular el registro del oyente
  4. Crear intento en TabActivity y transmitir i t cuando se quiere hacer algo al niño

En AndroidManifest.xml

<activity 
    android:name=".MyActivity" 
    android:label="@string/app_name" 
    <intent-filter> 
     <action android:name="com.mycompany.myApp.DO_SOMETHING" /> 
    </intent-filter> 
</activity> 

En MyActivity.java

public class MyActivity extends Activity { 

    private MyListener listener = null; 
    private Boolean MyListenerIsRegistered = false; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreated(savedInstanceState); 

     listener = new MyListener(); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 

     if (!MyListenerIsRegistered) { 
      registerReceiver(listener, new IntentFilter("com.mycompany.myApp.DO_SOMETHING")); 
      MyListenerIsRegisterd = true; 
     } 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 

     if (MyListenerIsRegistered) { 
      unregisterReceiver(listener); 
      MyListenerIsRegistered = false; 
     } 
    } 

    // Nested 'listener' 
    protected class MyListener extends BroadcastReceiver { 

     @Override 
     public void onReceive(Context context, Intent intent) { 

      // No need to check for the action unless the listener will 
      // will handle more than one - let's do it anyway 
      if (intent.getAction().equals("com.mycompany.myApp.DO_SOMETHING")) { 
       // Do something 
      } 
     } 
    } 
} 

En el TabActivity principal

private void MakeChildDoSomething() { 

    Intent i = new Intent(); 
    i.setAction("com.mycompany.myApp.DO_SOMETHING"); 
    sendBroadcast(i); 
} 
+0

así me gustaría evitar que si es posible. puedo acceder a la función pública del padre desde la actividad infantil sin ningún problema, debería poder hacer lo mismo para el otro lado, espero –

+0

@ android-developer: Tu elección pero es trivial de hacer y funciona. También significa que TabActivity 'padre' no necesita conocer los nombres de métodos específicos de sus hijos: todo lo que tiene que hacer es enviar un intento que diga 'Hacer esto' y la actividad secundaria luego lo maneja internamente. También es la forma más común para que las actividades se comuniquen entre sí. – Squonk

+0

@MisterSquonk: ¿me proporcionarías algún código sobre cómo lograr esto o si me dirigirías en la dirección correcta? lo apreciaría. –

6

estoy Actualmente se está depurando una aplicación de Android y se encontró con la misma necesidad. He encontrado una gran respuesta directa a esto con este fragmento de código:

String currentActivityId = getLocalActivityManager().getCurrentId(); 
Activity currentActivity = getLocalActivityManager().getActivity(currentActivityId); 

El identificador de aquí es el identificador dado al crear el TabSpec:

tabHost.newTabSpec("id").setIndicator(indicator).setContent(intent); 
+0

También me gusta su solución, de hecho acabo de reemplazar lo que tenía con él, ya que me permite obtener las actividades de varias pestañas y llamar a una interfaz común que cada actividad implementa. Me pregunto si para mi caso de uso, sin embargo, un oyente de pestañas (a través de broadcastreciever) es un mejor patrón de diseño? – littleK

4

Gracias, esto me ayudó a resolver un problema de simular !

Activity currentActivity = getLocalActivityManager().getActivity(_TabHost.getCurrentTabTag()); 
if(currentActivity != null && currentActivity instanceof iMyActivity) 
{ 
// pass to children 
((iMyActivity)currentActivity).onLaunchDelegate(); 
} 
16

He encontrado otra solución, probablemente más simple. Estoy seguro de que OP ya no necesita esto, pero tal vez alguien del futuro estará encantado de encontrarlo.

Así que, básicamente, para ejecutar un método público en su actividad niño, sólo tiene este pequeño fragmento de código en su padre (tabHost, home y message se toman de la configuración TabHost de OP):

tabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() { 
    @Override 
    public void onTabChanged(String tabId) { 
     Activity currentActivity = getCurrentActivity(); 
     if (currentActivity instanceof home) { 
      ((home) currentActivity).aPublicMethodFromClassHome(); 
     } 
     if (currentActivity instanceof messages) { 
      ((messages) currentActivity).aPublicMethodFromClassMessages(); 
     } 
    } 
}); 

Lo uso en mi aplicación. Funciona como un encanto;)

0

les resulta sencilla, lo utilizan en la aplicación de clase ActivityTab:

if(getCurrentActivity() instanceof YourSearchActivity){ 
      log("onClick: instance found"); 
      ((YourSearchActivity)getCurrentActivity()).activityPublicFuntion(); 
     } 
1

Desde este enlace, he encontrado esta solución simple (http://androidactivity.wordpress.com/2012/08/17/two-way-communication-between-tabactivity-and-its-child-tabs/):

Bueno, el truco es para almacenar el TAG asociado con cada pestaña, y usarlo para llamar a la actividad respectiva.

Al crear la ficha, se asocian con una etiqueta como siguiente:

yourTabHost.newTabSpec("Tab1"); 

digamos que queremos invocar un “refreshContent()” método que está dentro de la Actividad Tab1.

Es simple como llamar a estas líneas de la MainActivity:

ActivityTab1 activity = (ActivityTab1) getLocalActivityManager().getActivity("Tab1"); 
activity.refreshContent(); 

Y eso es todo!

Ahora, en la dirección opuesta, queremos llamar a algún método "updateMain()" dentro de MainActivity, desde la pestaña hija TabActivity1.

Al TabActivity1 sólo tendrá que llamar

((MainActivity)getParent()).updateMain(); 
Cuestiones relacionadas