Démarrer une activité à partir d'un fragment

91

J'ai 2 fragments avec sur les deux fragments un bouton. Lorsque j'appuie sur le bouton, j'aimerais démarrer une nouvelle activité. Mais je ne peux pas le faire fonctionner.

L'erreur que j'obtiens : ERREUR ici: incompatibilité de type: impossible de convertir de mFragmentFavorite en Fragment

Qu'est-ce que je fais mal?

MyFragmentPagerAdapter

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class MyFragmentPagerAdapter extends FragmentPagerAdapter{

    final int PAGE_COUNT = 3;

    /** Constructor of the class */
    public MyFragmentPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    /** This method will be invoked when a page is requested to create */
    @Override
    public Fragment getItem(int arg0) {

        switch(arg0){

        case 0:
            return new FavoriteActivity();
                    //ERROR: Type mismatch: cannot convert from FavoriteActivity to Fragment


        case 1:
            return new SettingsActivity();


        default:
            return null;

        }       
    }

    /** Returns the number of pages */
    @Override
    public int getCount() {
        return PAGE_COUNT;
    }
}

Activité favorite

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;

public class FavoriteActivity extends Activity{

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.main_favorite, container, false);


        OnClickListener listnr=new OnClickListener() {
            @Override
            public void onClick(View v) {
                  Intent i= new Intent("aFavorite");
                  startActivity(i);
            }
        };

          Button btn =(Button) v.findViewById(R.id.mainFavorite);
          btn.setOnClickListener(listnr);

          return v;
    }
}

Si FavoriteActivity étend des fragments, l'erreur a disparu, mais j'obtiens une erreur à findViewById(R.id.mainFavorite);et l'erreur est

La méthode findViewById (int) n'est pas définie pour le type FavoriteActivity

ÉDITER:

Lorsque j'appuie sur le bouton dans le fragment pour démarrer l'activité, l'application se bloque, c'est mon logcat

03-18 16:01:23.985: E/AndroidRuntime(1985): FATAL EXCEPTION: main
03-18 16:01:23.985: E/AndroidRuntime(1985): android.content.ActivityNotFoundException: No Activity found to handle Intent { act=FavoriteActivityList }
03-18 16:01:23.985: E/AndroidRuntime(1985):     at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1569)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at android.app.Instrumentation.execStartActivity(Instrumentation.java:1420)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at android.app.Activity.startActivityForResult(Activity.java:3446)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at android.app.Activity.startActivityForResult(Activity.java:3407)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at android.support.v4.app.FragmentActivity.startActivityFromFragment(FragmentActivity.java:826)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at android.support.v4.app.Fragment.startActivity(Fragment.java:838)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at com.example.spui.FavoriteActivity$1.onClick(FavoriteActivity.java:24)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at android.view.View.performClick(View.java:4211)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at android.view.View$PerformClick.run(View.java:17267)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at android.os.Handler.handleCallback(Handler.java:615)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at android.os.Handler.dispatchMessage(Handler.java:92)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at android.os.Looper.loop(Looper.java:137)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at android.app.ActivityThread.main(ActivityThread.java:4898)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at java.lang.reflect.Method.invokeNative(Native Method)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at java.lang.reflect.Method.invoke(Method.java:511)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
03-18 16:01:23.985: E/AndroidRuntime(1985):     at dalvik.system.NativeStart.main(Native Method)
mXX
la source
3
Peut-être ne devriez-vous pas étendre FragmentActivity mais plutôt Fragment?
span
1
Eh bien, pour celui que vous n'utilisez pas Fragments. Au moins non dans le code que vous avez publié.
adneal

Réponses:

247

mFragmentFavoritedans votre code est un FragmentActivityqui n'est pas la même chose qu'un Fragment. C'est pourquoi vous obtenez la non-concordance de types. De plus, vous ne devriez jamais faire appel newà un Activitycar ce n'est pas la bonne façon d'en démarrer un.

Si vous souhaitez démarrer une nouvelle instance de mFragmentFavorite, vous pouvez le faire via un fichier Intent.

D'un Fragment:

Intent intent = new Intent(getActivity(), mFragmentFavorite.class);
startActivity(intent);

D'un Activity

Intent intent = new Intent(this, mFragmentFavorite.class);
startActivity(intent);

Si vous voulez commencer à la aFavoriteplace, mFragmentFavoriteil vous suffit de changer leurs noms dans le fichier créé Intent.

De plus, je recommande de changer les noms de vos classes pour être plus précis. Appeler quelque chose mFragmentFavoriteest inapproprié dans la mesure où ce n'est pas Fragmentdu tout. De plus, les déclarations de classe en Java commencent généralement par une majuscule. Vous feriez bien de nommer votre classe par exemple FavoriteActivitypour être plus précis et conforme aux conventions linguistiques. Vous devrez également renommer le fichier en FavoriteActivity.java si vous choisissez de le faire, car Java exige que les noms de classe correspondent au nom de fichier.

MISE À JOUR

En outre, il semble que vous vouliez réellement mFragmentFavoriteêtre un Fragmentplutôt qu'un en FragmentActivityfonction de votre utilisation de onCreateView. Si vous voulez mFragmentFavoriteêtre un, Fragmentmodifiez la ligne de code suivante:

public class mFragmentFavorite extends FragmentActivity{

Faites plutôt lire ceci:

public class mFragmentFavorite extends Fragment {
Michael Celey
la source
D'accord, je vais mettre à jour le code dans le premier message. Mais je ne comprends pas tout à fait le mContextReference. Je vais mettre à jour le code avec ce que j'ai et de meilleurs noms, donnez-moi 5 min
mXX
C'est un exemple de référence à un Fragmentou un Activity. Si vous utilisez le code à l'intérieur d'une de ces classes, vous pouvez simplement le remplacer mContextReferencepar getActivity()for Fragmentou thisfor Activitysur la première ligne et thispour la deuxième ligne. Je mettrai à jour la réponse pour être plus claire.
Michael Celey
D'accord, j'ai mis à jour la question avec de meilleurs noms et les conseils que vous m'avez donnés. Je vais essayer maintenant de mettre en œuvre votre suggestion pour essayer de la faire fonctionner. Merci pour l'aide
mXX
Oui, je l'ai changé en Fragment mais j'obtiens l'erreur sur le btn pour trouver l'ID "La méthode findViewById (int) n'est pas définie pour le type FavoriteActivity"
mXX
2
Si vous faites un Fragmentchangement puis findViewByIdà v.findViewById. Il n'y a pas de findViewByIdfonction Fragment, vous devez donc d' getViewabord appeler puis appeler findViewByIdcela. Dans votre cas cependant, vous avez déjà votre point de vue onCreateViewet ce serait votre variable v.
Michael Celey
21

Vous devez utiliser getActivity()pour lancer des activités à partir de fragments

Intent intent = new Intent(getActivity(), mFragmentFavorite.class);
startActivity(intent);

De plus, vous devriez nommer les classes avec des majuscules: MFragmentActivityau lieu de mFragmentActivity.

menteur
la source
4

Si vous utilisez getActivity (), vous devez vous assurer que l'activité d'appel est déjà ajoutée . Si l'activité n'a pas été ajoutée dans ce cas, vous pouvez obtenir null lorsque vous appelez getActivity ()

dans de tels cas, getContext () est sûr

puis le code de démarrage de l'activité sera légèrement modifié comme,

Intent intent = new Intent(getContext(), mFragmentFavorite.class);
startActivity(intent);

Activity, Service and Application étend la classe ContextWrapper afin que vous puissiez utiliser this ou getContext () ou getApplicationContext () à la place du premier argument.

Jayakrishnan
la source
"Si vous utilisez getActivity (), vous devez vous assurer que l'activité d'appel est déjà ajoutée." - Que signifie cette ligne pour un débutant?
Palak Jain
@PalakJain Cela signifie que l'état de l'activité (actif à détruit) continue de changer en fonction de x raisons. Une activité doit être en état actif lorsque vous effectuez quelque chose dessus. L'activité est à l'état actif si sa durée de vie se situe entre onResume et onPause.
Jayakrishnan
Eh bien, cela a du sens. Merci!
Palak Jain
3

J'utilise ceci dans mon fragment.

Button btn1 = (Button) thisLayout
            .findViewById(R.id.btnDb1);

    btn1.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Intent intent = new Intent(getActivity(), otherActivity.class);
            ((MainActivity) getActivity()).startActivity(intent);

        }
    });

    return thisLayout;
}
Sara Zakizadeh
la source
0

Vous devrez peut-être remplacer getActivity () par MainActivity.this pour ceux qui rencontrent des problèmes avec cela.

ADL
la source
0

Démarrer une nouvelle activité à partir d'un fragment:

Intent intent = new Intent(getActivity(), TargetActivity.class);
startActivity(intent);

Démarrer une nouvelle activité à partir d'une activité:

Intent intent = new Intent(this, TargetActivity.class);
startActivity(intent);
Abhay Bhusari
la source
0

avec Kotlin j'exécute ce code:

requireContext().startActivity<YourTargetActivity>()

Alexandr Kolesnik
la source
Quand j'essaye ce code, j'obtiens:None of the following functions can be called with the arguments supplied. startActivity(Intent!) defined in android.content.Context startActivity(Intent!, Bundle?) defined in android.content.Context
Tim
@Tim Vous aurez probablement besoin d' Android KTX pour que le code fonctionne.
Edric