3 votes

Retourner à la TabActivity précédente

Comment expliquer mon problème ?

J'ai une application qui utilise des onglets (par Intents, pas par vues). J'ai implémenté la navigation à l'intérieur de chaque vue sans problème mais j'ai besoin de lancer un lecteur vidéo à partir d'une ListView à l'intérieur d'une des activités en plein écran et en mode paysage (donc sans onglets). Mais lorsque je veux quitter le lecteur (soit en appuyant sur back ou en appelant finish() ;), mon application est fermée (pas d'exception dans le LogCat) et retourne à l'écran principal. Ce dont j'ai besoin, c'est que lorsque je quitte l'activité plein écran (lancée pour le lecteur), je revienne à mon application, avec les onglets.

Voici mon code :

//Main activity : 

package com.ccn;

import android.app.TabActivity;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.widget.TabHost;

public class CCNMain extends TabActivity {
    public static TabHost tabHost;
    static CCNMain  myActivity = null;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        myActivity = this;

        Resources res = getResources();
        tabHost = getTabHost();
        TabHost.TabSpec spec; // reusable tabspec for each tab
        Intent intent;

        intent = new Intent().setClass(this, NewsGroup.class);
        spec = tabHost.newTabSpec("nnews")
        .setIndicator("A la une",res.getDrawable(R.drawable.home))
        .setContent(intent);
        tabHost.addTab(spec);

        /*intent = new Intent().setClass(this, ArticlesGroup.class);
        spec = tabHost.newTabSpec("aarticles")
        .setIndicator("Articles",res.getDrawable(R.drawable.articles))
        .setContent(intent);
        tabHost.addTab(spec);*/

        intent = new Intent().setClass(getApplicationContext(), ContactGroup.class);
        spec = tabHost.newTabSpec("vvideos")
        .setIndicator("Vidéos",res.getDrawable(R.drawable.video))
        .setContent(intent);
        tabHost.addTab(spec);

        intent = new Intent().setClass(getApplicationContext(), ContactGroup.class);
        spec = tabHost.newTabSpec("ccontact")
        .setIndicator("Contact",res.getDrawable(R.drawable.contact))
        .setContent(intent);
        tabHost.addTab(spec);

        tabHost.setCurrentTab(0);
    }
}

//ContactGroup : 
package com.ccn;

import java.util.ArrayList;

import android.app.ActivityGroup;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class ContactGroup extends ActivityGroup {
    // Keep this in a static variable to make it accessible for all the nested activities, lets them manipulate the view  
    public static ContactGroup groupContact;  

        // Need to keep track of the history if you want the back-button to work properly, don't use this if your activities requires a lot of memory.  
    private ArrayList<View> history;  
  @Override
    protected void onCreate(Bundle savedInstanceState) {  
          super.onCreate(savedInstanceState);  
          this.history = new ArrayList<View>();  
          groupContact = this;  

              // Start the root activity within the group and get its view  
          View view = getLocalActivityManager().startActivity("idHoraireActivity", new  
                                            Intent(this,ContactActivity.class)  
                                            .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))  
                                            .getDecorView();  

              // Replace the view of this ActivityGroup  
          replaceView(view);  

       }  

    public void replaceView(View v) {  
                // Adds the old one to history  
        history.add(v);  
                // Changes this Groups View to the new View.  
        setContentView(v);  
    }  

    public void back() {  
        if(history.size() > 1) {  
            history.remove(history.size()-1);  
            setContentView(history.get(history.size()-1));  
        }else {  
            finish();  
        }  
    }  
    //@Override  
    public void onBackPressed() {  
        ContactGroup.groupContact.back();  
        return;  
    }

}

//ContactActivity:
package com.ccn;

import java.io.IOException;

import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.Toast;
import android.widget.VideoView;

public class ContactActivity extends Activity {
    static ContactActivity bidule = null;
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.videos);
        bidule = this;
        Button btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent i = new Intent();
                i.setClass(getApplicationContext(), videoPlayerActivity.class);
                //i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                bidule.startActivity(i);
                ContactActivity.this.startActivityForResult(i, 0);
            }
        });

    }

}

//VideoPlayerActivity:
package com.ccn;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.VideoView;

public class videoPlayerActivity extends Activity {

    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.videos);

        //the VideoView will hold the video
        String url = // Video url;

        Button btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                // TODO Auto-generated method stub
                finish();
            }
        });
    }

}

Et voici mon Manifeste :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.ccn"
      android:versionCode="1"
      android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET"></uses-permission>

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".CCNMain"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="ArticlesGroup"></activity>
        <activity android:name="ContactGroup"></activity>
        <activity android:name="NewsGroup"></activity>
        <activity android:name="NewsActivity"></activity>
        <activity android:name="ArticlesAvtivity"></activity>
        <activity android:name="ContactActivity"></activity>
        <activity android:name="videoPlayerActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:screenOrientation="landscape"></activity>

    </application>
</manifest>

Merci pour votre aide. Je pense que c'est lié à l'endroit où j'appelle startActivity et aux drapeaux Intent. Qu'en pensez-vous ?

1voto

Pankaj Kumar Points 19620

Édité

/Main activity : 

package com.ccn;

import android.app.TabActivity;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.widget.TabHost;

public class CCNMain extends TabActivity {
    public static TabHost tabHost;
    static CCNMain  myActivity = null;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        myActivity = this;

        Resources res = getResources();
        tabHost = getTabHost();
        TabHost.TabSpec spec; // reusable tabspec for each tab
        Intent intent;

        intent = new Intent().setClass(this, NewsGroup.class);
        spec = tabHost.newTabSpec("nnews")
        .setIndicator("A la une",res.getDrawable(R.drawable.home))
        .setContent(intent);
        tabHost.addTab(spec);

        /*intent = new Intent().setClass(this, ArticlesGroup.class);
        spec = tabHost.newTabSpec("aarticles")
        .setIndicator("Articles",res.getDrawable(R.drawable.articles))
        .setContent(intent);
        tabHost.addTab(spec);*/

        intent = new Intent().setClass(getApplicationContext(), ContactGroup.class);
        spec = tabHost.newTabSpec("vvideos")
        .setIndicator("Vidéos",res.getDrawable(R.drawable.video))
        .setContent(intent);
        tabHost.addTab(spec);

        intent = new Intent().setClass(getApplicationContext(), ContactGroup.class);
        spec = tabHost.newTabSpec("ccontact")
        .setIndicator("Contact",res.getDrawable(R.drawable.contact))
        .setContent(intent);
        tabHost.addTab(spec);

        tabHost.setCurrentTab(0);
    }
}

//ContactGroup : 
package com.ccn;

import java.util.ArrayList;

import android.app.ActivityGroup;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class ContactGroup extends ActivityGroup {
    // Keep this in a static variable to make it accessible for all the nested activities, lets them manipulate the view  
    public static ContactGroup groupContact;  

        // Need to keep track of the history if you want the back-button to work properly, don't use this if your activities requires a lot of memory.  
    private ArrayList<View> history;  
  @Override
    protected void onCreate(Bundle savedInstanceState) {  
          super.onCreate(savedInstanceState);  
          this.history = new ArrayList<View>();  
          groupContact = this;  

              // Start the root activity within the group and get its view  
          View view = getLocalActivityManager().startActivity("idHoraireActivity", new  
                                            Intent(this,ContactActivity.class)  
                                            .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))  
                                            .getDecorView();  

              // Replace the view of this ActivityGroup  
          replaceView(view);  

       }  

    public void replaceView(View v) {  
                // Adds the old one to history  
        history.add(v);  
                // Changes this Groups View to the new View.  
        setContentView(v);  
    }  

    public void back() {  
        if(history.size() > 1) {  
            history.remove(history.size()-1);  
            setContentView(history.get(history.size()-1));  
        }else {  
            finish();  
        }  
    }  
    //@Override  
    public void onBackPressed() {  
        ContactGroup.groupContact.back();  
        return;  
    }

}

//ContactActivity:
package com.ccn;

import java.io.IOException;

import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.Toast;
import android.widget.VideoView;

public class ContactActivity extends Activity {
    //static ContactActivity bidule = null;
      ContactGroup contactGroup = null;
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.videos);
        //bidule = this;
        contactGroup = new ContactGroup();

        Button btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                // TODO Auto-generated method stub
                View view = getLocalActivityManager().startActivity("videoPlayerActivity", new  
                                            Intent(this,videoPlayerActivity.class)  
                                            .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))  
                                            .getDecorView();
                contactGroup.replaceView(view);
            }
        });

    }

}

//VideoPlayerActivity:
package com.ccn;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.VideoView;

public class videoPlayerActivity extends Activity {
     ContactGroup contactGroup = null;

    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.videos);
         ContactGroup contactGroup = new  ContactGroup();

        //the VideoView will hold the video
        String url = // Video url;

        Button btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                // TODO Auto-generated method stub
                 contactGroup.back();
            }
        });
    }

Résumé :

Vous devez appeler les méthodes repalaceView et back de votre groupe d'activités. Lorsque vous voulez démarrer une nouvelle activité, utilisez replaceView() et lorsque vous souhaitez terminer votre activité, utilisez back()

0voto

Rakul Points 39

J'ai mis en œuvre le même type de cas. Mais je n'ai pas utilisé l'ActivityGroup. Lors des tests, il est apparu clairement que sa réponse n'était pas étanche. Lorsque je lance l'activité Mediaplayer et que je place une nouvelle activité dans la pile, le système d'exploitation gère correctement l'événement back.

public class VideoActivity extends Activity {
private ListView mListView;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    mListView = (ListView)findViewById(R.id.list);
    mListView.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Intent intent = new Intent().setClass(view.getContext(), ViewVideoActivity.class);
            startActivity(intent);
        }
    });
}

L'activité VieoVideoActivity est une activité plein écran forcée en paysage, sans implémentation d'événements clés.

0voto

chiwai Points 11

J'espère avoir bien compris votre demande (merci de me corriger). Il y a plusieurs onglets dans votre TabActivity, tous sauf un associés à une autre Activity qui devrait se trouver "à l'intérieur" de la TabActivity. Pour la vidéo, vous voulez qu'elle soit lancée au même niveau que la TabActivity (qui n'est pas à l'intérieur). Ainsi, le système peut gérer l'événement "back" de la VideoActivity.

|     |
|     |
|T (1)| <- tab activity with tab#1
-------

Sélectionnez l'onglet n° 2 :

|     |
|     |
|T (2)| <- tab activity with tab#2
-------

Sélectionnez l'onglet #vidéo :

|     |
|Video| <- video activity
|T (2)| <- tab activity with tab#2
-------

Puisque vous pouvez créer la "sous-activité" sans problème, je vous montre ici comment créer une activité externe Intent :

private void createExternalTab(Class clazz, String tag, String label, int iconResId) {
    // intent to launch the activity externally
    final Intent intent = new Intent(this, clazz);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    tabHost.addTab(tabHost.newTabSpec(tag)
            .setContent(R.id.dummy)
            .setIndicator(label, iconResId));
    // find the recently added tab
    TabWidget w = tabHost.getTabWidget();
    View view = w.getChildAt(w.getChildCount() - 1);
    // here is the magic!
    view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startActivity(intent);
        }
    });
}

Voici la présentation de l'activité TabActivity :

<?xml version="1.0" encoding="utf-8"?>

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

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <View
                android:id="@+id/dummy"
                android:layout_width="0dp"
                android:layout_height="0dp"/>

            </FrameLayout>

        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:orientation="horizontal"
            android:showDividers="none"/>
    </RelativeLayout>

</TabHost>

Note 1 : mon code fonctionne avec FragmentActivity

Note 2 : Le point clé ici est : mapper le contenu de l'onglet à un élément invisible à l'intérieur de R.id.tabcontent. Ensuite, modifiez l'onClickListener de l'onglet de manière à ce qu'un Intent soit appelé sous la TabActivity, et non lancé par le TabWidget/TabHost.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X