2010-12-06 34 views
3

Lorsque j'imprime une TabActivity dans une autre TabActivity, startActivityForResult échoue lorsqu'elle est appelée à partir de la tabactivité interne. La nouvelle activité démarre, mais je reçois un message d'erreur:Android: Les tabactivités imbriquées ne fonctionnent pas avec startActivityForResult

startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: Intent 

et onActivityResult est jamais appelée lorsque l'activité revient.

Code à reproduire ci-dessous. Quatre classes, MyActivity est la classe principale avec deux onglets, NestedTab comporte trois onglets, tous les onglets contiennent SimpleActivity avec un bouton qui appelle SimpleDialog:

public class MyActivity extends TabActivity { 
/** 
* Called when the activity is first created. 
*/ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    // Populate a couple of tabs 
    TabHost tabHost = getTabHost(); // The activity TabHost 
    TabHost.TabSpec spec; // Resusable TabSpec for each tab 
    Intent intent; // Reusable Intent for each tab 

    // Create an Intent to launch an Activity for the tab (to be reused) 
    intent = new Intent().setClass(this, SimpleActivity.class); 
    // Initialize a TabSpec for each tab and add it to the TabHost 
    spec = tabHost.newTabSpec("simple").setIndicator("Simple") 
        .setContent(intent); 
    tabHost.addTab(spec); 

    // Repeat 
    intent = new Intent().setClass(this, NestedTab.class); 
    spec = tabHost.newTabSpec("nested").setIndicator("Nested tabs") 
        .setContent(intent); 
    tabHost.addTab(spec); 

} 
} 

public class NestedTab extends TabActivity { 
/** 
* Called when the activity is first created. 
*/ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    TabHost tabHost = getTabHost(); // The activity TabHost 
    TabHost.TabSpec spec; // Resusable TabSpec for each tab 
    Intent intent; // Reusable Intent for each tab 

    // Create an Intent to launch an Activity for the tab (to be reused) 
    intent = new Intent(this, SimpleActivity.class); 

    String tabs[]= {"One", "Two", "Three"}; 
    for (String s : tabs) 
    { 
     intent.putExtra("name", s); 
     spec = tabHost.newTabSpec(s).setIndicator(s).setContent(intent); 
     tabHost.addTab(spec); 
    } 


} 

public class SimpleActivity extends Activity { 
Button mBtn; 
Context mCtx; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.simple); 
    mCtx = this; 
    mBtn = (Button) findViewById(R.id.btn); 
    mBtn.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View view) { 
      //To change body of implemented methods use File | Settings | File Templates. 
      startActivityForResult(new Intent(mCtx, SimpleDisplay.class), 1); 
     } 
    }); 
} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); //To change body of overridden methods use File | Settings | File Templates. 
    Toast.makeText(this, "Activity finished", Toast.LENGTH_LONG).show(); 
} 
} 


public class SimpleDisplay extends Activity { 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    TextView text = new TextView(this); 
    text.setText("Just hit back button"); 
    setContentView(text); 

} 
} 

Pas en mesure de coller les fichiers xml, mais principale est identique à l'étape 4: http://developer.android.com/resources/tutorials/views/hello-tabwidget.html

et simple est juste un textview et un bouton.

Toute aide appréciée.

+1

Vous devez repenser la conception de votre application si vous imbriquez un 'TabActivity' dans un autre' TabActivity'. –

+0

Nous pensons que c'est la façon naturelle de présenter notre jeu de données et c'est une façon très courante de le faire. Par exemple. appstore sur iphone a Top 25 avec des options de sous-menu Top payé, top gratuit et top recettes. – Bitt

Répondre

3

Essayez SimpleActivity.this.startActivity ou ((Activity) view.getContext()).startActivity au lieu de seulement startActivity. Vous déclenchez l'activité à partir de votre OnClickListener au lieu de votre Activity sinon, d'où l'erreur et l'absence de rappel au onActivityResult de l'activité.

EDIT: Ah, j'ai manqué le bit double imbriqué. Les choses deviennent bizarres quand vous doublez TabActivity avec des intentions aux deux niveaux - regardez le code source de TabActivity pour voir ce qui s'y passe, et vous devriez être capable d'émuler son comportement si vous le voulez vraiment.

Le plus long et le plus court est que votre onActivityResult ne sera propagé que d'un niveau; Si vous voulez vraiment créer un sous-onglet basé sur l'intention (par opposition aux onglets basés sur l'intention avec des sous-onglets basés sur la vue normale), l'onglet parent (imbriqué seul) doit déclencher l'intention. Pour ce faire, essayez de définir votre onglet imbriqué unique pour avoir une méthode comme appelée quelque chose comme startActivityAndDispatchToChild, et appelez cela de l'enfant avec getParent().startActivityAndDispatchToChild. Avoir cette méthode startActivityForResult, et remplacer la méthode getActivityResult sur l'onglet imbriqué unique utiliser le code revenant de l'enfant pour savoir quel enfant à déporter. En utilisant ce code, appelez getLocalActivity().getActivity(whateverTag) pour l'expédier à la sous-activité appropriée.

Mais ne faites pas cela. Faites en sorte que votre activité de deuxième niveau utilise le contenu basé sur View plutôt que sur le contenu Intent; Si vous voulez vraiment séparer les sous-pages, écrivez une classe ViewGroup personnalisée pour gérer le contenu de chaque sous-onglet.

+0

Aucun de ces deux aide malheureusement. Notez aussi que si le Nestedtab est fait en classe principale (en changeant le mainfest) pour que ce soit la seule tabactivité, tout fonctionne bien ... Se pourrait-il que le contexte soit foiré car la tabactivité est créée à l'intérieur de la première la tabactivité en quelque sorte? – Bitt

+1

A droite, j'avais l'impression que quelque chose comme ça serait la réponse. Merci! – Bitt

+0

une explication plutôt artificielle, mais encore comblé le fossé. étant dans une situation similaire, mon code: Intention intention = new Intent (getParent(), StatusHelperActivity.class); startActivityForResult (intention, 0); ne fonctionnait pas car la deuxième ligne aurait dû être getParent().startActivityForResult (intention, 0); Cela étant ajouté, il n'est vraiment pas nécessaire d'abandonner les activités en faveur des extensions Viewgroup maladroites qui n'ont aucune trace de vie (cycle ^^). +1 – kellogs