2009-08-20 14 views
33

Aquí está el trato. Tengo una aplicación con tres pestañas. A través de varias interacciones con los elementos en las pestañas, termino lanzando otras actividades. El cliente ha revisado esto y desea que las actividades se inicien "dentro" de las pestañas, por lo que las pestañas permanecen visibles y si el usuario hace clic en la pestaña vuelve a la actividad original definida en la función setContent. ¿Es esto posible y cómo lo haré con otras actividades? (es decir, las actividades del niño, no la que define el TabHost y tiene acceso a llamar a setContent)?Iniciando actividades dentro de una pestaña en Android

Respuesta

44

Es posible iniciar actividades dentro de las pestañas. Por lo tanto, establezca el contenido de la especificación tabs en un ActivityGroup en lugar de una actividad normal. .

tabHost.addTab(tabHost.newTabSpec("Tab") 
       .setIndicator("Tab") 
       .setContent(new Intent(this, YourActivityGROUP.class) 
       .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))); 

Desde dentro de ese ActivityGroup a continuación, puede iniciar otra actividad como ésta, que sólo actualiza el contentView de la pestaña que está en

class YourActivityGROUP extends ActivityGroup{ 

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

     //you van get the local activitymanager to start the new activity 

     View view = getLocalActivityManager() 
           .startActivity("ReferenceName", new 
     Intent(this,YourActivity.class) 
           .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)) 
           .getDecorView(); 
     this.setContentView(view); 

    } 
} 
+1

gracias por esto ... en realidad, creo que esta debería ser la manera correcta de avanzar para implementar este tipo de funcionalidad, ya que proporciona una mejor capacidad de mantenimiento del código. – samiq

+0

¿Hay otra manera también pero elegante? En realidad no ... Siempre puede guardar la instancia de su clase TabActivity en una clase de aplicación extendida (para evitar la estática global).Cuando necesite iniciar una actividad nueva, debe llamar a la clase de Aplicación para devolver la instancia de TabActivity e iniciar un método que borre las pestañas y las vuelva a crear, pero reemplazando la Actividad actual por la nueva. Si alguien está interesado, puedo entrar en más detalles. – glr

+0

hola, gracias .. puedo llamar actividad nueva en la misma pestaña, pero el problema viene cuando vuelvo a la actividad anterior. Llamo a la actividad B del grupo de actividades A, ahora quiero pasar al grupo de actividades A nuevamente. ¿Pueden darme una pista? Gracias. –

0

commonsware.com es correcto, no es posible. Tuve un problema similar, pero solo se lanzó una actividad. Sacrifiqué un poco de mi arquitectura y eliminé la actividad que se lanzó desde el interior de la pestaña. Puse el código en una Vista y luego agregué un ViewAnimator a la actividad de la pestaña. Anulo el botón Atrás y elimino esa vista si está arriba, o de lo contrario dejo que el botón Atrás funcione normalmente.

Esto lo fingió lo suficientemente bien, y para solo 1 actividad estrechamente relacionada, no voy a perder el sueño por las consideraciones de diseño.

11

Aquí es mi solución

public class ActivityStack extends ActivityGroup { 

    private Stack<String> stack; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if (stack == null) stack = new Stack<String>(); 
    //start default activity 
    push("FirstStackActivity", new Intent(this, FirstStackActivity.class)); 
    } 

    @Override 
    public void finishFromChild(Activity child) { 
    pop(); 
    } 

    @Override 
    public void onBackPressed() { 
    pop(); 
    } 


    public void push(String id, Intent intent) { 
    Window window = getLocalActivityManager().startActivity(id, intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)); 
    if (window != null) { 
     stack.push(id); 
     setContentView(window.getDecorView()); 
    } 
    } 

    public void pop() { 
    if (stack.size() == 1) finish(); 
    LocalActivityManager manager = getLocalActivityManager(); 
    manager.destroyActivity(stack.pop(), true); 
    if (stack.size() > 0) { 
     Intent lastIntent = manager.getActivity(stack.peek()).getIntent(); 
     Window newWindow = manager.startActivity(stack.peek(), lastIntent); 
     setContentView(newWindow.getDecorView()); 
    } 
    } 
} 

Pestaña de lanzamiento

Intent intent = new Intent().setClass(this, ActivityStack.class); 
TabHost.TabSpec spec = tabHost.newTabSpec("tabId") 
spec.setContent(intent); 

Call siguiente actividad

public class FirstStackActivity extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    TextView textView = new TextView(this); 
    textView.setText("First Stack Activity "); 
    textView.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Intent intent = new Intent(); 
      intent.setClass(getParent(), SecondStackActivity .class); 
      ActivityStack activityStack = (ActivityStack) getParent(); 
      activityStack.push("SecondStackActivity", intent); 


     } 
    }); 
    setContentView(textView); 
    } 
} 

Call siguiente otra vez

public class SecondStackActivity extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    TextView textView = new TextView(this); 
    textView.setText("First Stack Activity "); 
    textView.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Intent intent = new Intent(); 
      intent.setClass(getParent(), ThirdStackActivity .class); 
      ActivityStack activityStack = (ActivityStack) getParent(); 
      activityStack.push("ThirdStackActivity", intent); 


     } 
    }); 
    setContentView(textView); 
    } 
} 

Obras en emulador 2.2

+1

Tenga en cuenta que 'ActivityGroup' ahora está en desuso. – CommonsWare

+0

Este código funciona como se esperaba. –

+0

En realidad, hay un error bastante grande: si comienzas desde la actividad A hasta la actividad B y luego terminas() en la actividad A, el código anterior terminará la actividad B. –

0

¿Qué hay de 2 barra de pestañas en este problema. En primer lugar 1 es el menú de barra de pestañas inferior, segundo es la parte superior de barra de pestañas, que son diferentes de actividad y XML

1

puede utilizar

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 

para cada actividad se establece como contenido para tabSpec, y se creará esta actividad cada vez que presiona en la pestaña

0

¿Cómo puedo abrir un fragmento o actividad de un control giratorio en la barra de herramientas?

import android.content.Intent; import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.Toolbar; 
import android.util.Log; import android.view.Menu; 
import android.view.MenuItem; import android.view.View; 
import android.widget.AdapterView; import android.widget.ArrayAdapter; 
import android.widget.Spinner; 


> public class MainActivity extends AppCompatActivity { 
> 
>  @Override 
>  protected void onCreate(Bundle savedInstanceState) { 
>   super.onCreate(savedInstanceState); 
>   setContentView(R.layout.activity_main); 
> 
>   //Appbar 
>   Toolbar toolbar = (Toolbar) findViewById(R.id.appbar); 
>   setSupportActionBar(toolbar); 
>   getSupportActionBar().setDisplayShowTitleEnabled(false); 
> 
>   //Appbar page filter 
>   Spinner cmbToolbar = (Spinner) findViewById(R.id.CmbToolbar); 
> 
>   ArrayAdapter<String> adapter = new ArrayAdapter<>(
>     getSupportActionBar().getThemedContext(), 
>     R.layout.appbar_filter_title, 
>     new String[]{"Opción 1 ", "Opción 2 ", "Opción 3 "}); 
> 
>   adapter.setDropDownViewResource(R.layout.appbar_filter_list); 
> 
>   cmbToolbar.setAdapter(adapter); 
> 
>   cmbToolbar.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 
>    @Override 
>    public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) { 
>     //... Acciones al seleccionar una opción de la lista 
>     Log.i("Toolbar 3", "Seleccionada opción " + position); 
> 
>     Fragment f = null; 
> 
>     switch(position) { 
>      case 0: 
>       f = Fragment2.newInstance(); 
>       break; 
> 
>      case 1: 
>       f = Fragment1.newInstance(); 
>       break; 
> 
>     } 
>    } 
> 
>    @Override 
>    public void onNothingSelected(AdapterView<?> adapterView) { 
>     //... Acciones al no existir ningún elemento seleccionado 
>    } 
>   }); 
>  } 
> 
>  @Override 
>  public boolean onCreateOptionsMenu(Menu menu) { 
>   // Inflate the menu; this adds items to the action bar if it is present. 
>   getMenuInflater().inflate(R.menu.menu_main, menu); 
>   return true; 
>  } 
> 
>  @Override 
>  public boolean onOptionsItemSelected(MenuItem item) { 
>   // Handle action bar item clicks here. The action bar will 
>   // automatically handle clicks on the Home/Up button, so long 
>   // as you specify a parent activity in AndroidManifest.xml. 
>   int position = item.getItemId(); 
> 
>   Fragment f = null; 
> 
>   switch(position) { 
>    case 0: 
>     f = Fragment2.newInstance(); 
>     break; 
> 
>    case 1: 
>     f = Fragment1.newInstance(); 
>     break; 
> 
>    case 2: 
>     Intent intent = new Intent(getApplicationContext(), Fragment1.class); 
>     startActivity(intent); 
>     break; 
> 
>   } 
>   return super.onOptionsItemSelected(item); 
>  } 
> 
> 
>  public Fragment getItem(int position) { 
> 
>   Fragment f = null; 
> 
>   switch(position) { 
>    case 0: 
>     f = Fragment2.newInstance(); 
>     break; 
> 
>    case 1: 
>     f = Fragment1.newInstance(); 
>     break; 
> 
>    case 2: 
>     Intent intent = new Intent(getApplicationContext(), Fragment1.class); 
>     startActivity(intent); 
>     break; 
> 
>   } 
> 
>   return f; 
>  } } 
Cuestiones relacionadas