Inizia un'attività da un frammento


91

Ho 2 frammenti con su entrambi i frammenti un pulsante. Quando premo il pulsante vorrei iniziare una nuova attività. Ma non riesco a farlo funzionare.

L'errore che ricevo: ERRORE qui: Tipo non corrispondente: impossibile convertire da mFragmentFavorite a Fragment

Che cosa sto facendo di sbagliato?

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;
    }
}

Attività preferita

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;
    }
}

Se FavoriteActivity estende i frammenti, l'errore è sparito, ma poi ottengo un errore in findViewById(R.id.mainFavorite);e l'errore è

Il metodo findViewById (int) non è definito per il tipo FavoriteActivity

MODIFICARE:

Quando premo il pulsante nel frammento per avviare l'attività, l'app va in crash questo è il mio 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)

3
Forse non dovresti estendere FragmentActivity ma piuttosto Fragment?
periodo

1
Beh, per quello che non stai usando Fragments. Almeno no nel codice che hai pubblicato.
adneal

Risposte:


247

mFragmentFavoritenel tuo codice è un FragmentActivityche non è la stessa cosa di un file Fragment. Ecco perché ottieni la mancata corrispondenza del tipo. Inoltre, non dovresti mai chiamare newun in Activityquanto non è il modo corretto per avviarne uno.

Se vuoi avviare una nuova istanza di mFragmentFavorite, puoi farlo tramite un file Intent.

Da un Fragment:

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

Da un Activity

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

Se vuoi iniziare aFavoriteinvece di mFragmentFavoriteallora devi solo cambiare i loro nomi nel file Intent.

Inoltre, consiglio di cambiare i nomi delle classi per essere più accurati. Chiamare qualcosa mFragmentFavoriteè improprio in quanto non lo è Fragmentaffatto. Inoltre, le dichiarazioni di classe in Java in genere iniziano con una lettera maiuscola. Faresti bene a nominare la tua classe qualcosa come FavoriteActivityessere più accurato e conforme alle convenzioni linguistiche. Sarà inoltre necessario rinominare il file in FavoriteActivity.java se si sceglie di farlo poiché Java richiede che i nomi delle classi corrispondano al nome del file.

AGGIORNARE

Inoltre, sembra che in realtà volessi mFragmentFavoriteessere un Fragmentinvece di un FragmentActivitybasato sul tuo utilizzo di onCreateView. Se vuoi mFragmentFavoriteessere un, Fragmentmodifica la seguente riga di codice:

public class mFragmentFavorite extends FragmentActivity{

Fallo invece leggere:

public class mFragmentFavorite extends Fragment {

Va bene, aggiornerò il codice nel primo post. Ma non capisco bene mContextReference. Aggiornerò il codice con quello che ho e nomi migliori, dammi 5 min
mXX

È un esempio di riferimento a un Fragmento un file Activity. Se stai usando il codice all'interno di una di queste classi, puoi semplicemente sostituire mContextReferencecon getActivity()for Fragmento thisfor Activitysulla prima riga e thissulla seconda riga. Aggiornerò la risposta per essere più chiaro.
Michael Celey

Ok, ho aggiornato la domanda con nomi migliori e il consiglio che mi hai dato. Cercherò ora di implementare il tuo suggerimento per provare a farlo funzionare. Grazie per l'aiuto
mXX

Sì, l'ho cambiato di nuovo in Fragment ma ottengo l'errore su btn per trovare l'ID "Il metodo findViewById (int) non è definito per il tipo FavoriteActivity"
mXX

2
Se lo fai, Fragmentcambia findViewByIdin v.findViewById. Non è presente alcuna findViewByIdfunzione, Fragmentquindi devi getViewprima chiamare e poi chiamarla findViewById. Nel tuo caso, però, hai già la tua vista onCreateViewe quella sarebbe la tua variabile v.
Michael Celey

21

Dovresti usare getActivity()per lanciare attività da frammenti

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

Inoltre, dovresti nominare le classi con maiuscole: MFragmentActivityinvece di mFragmentActivity.


4

Se stai usando getActivity (), devi assicurarti che l'attività chiamante sia già stata aggiunta . Se l'attività non è stata aggiunta in questo caso, potresti ottenere null quando chiami getActivity ()

in questi casi getContext () è sicuro

quindi il codice per iniziare l'attività verrà leggermente modificato come,

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

Activity, Service and Application estende la classe ContextWrapper in modo da poter utilizzare this o getContext () o getApplicationContext () al posto del primo argomento.


'Se stai usando getActivity (), devi assicurarti che l'attività chiamante sia già stata aggiunta .'- Cosa significa questa riga per un principiante?
Palak Jain

@PalakJain Ciò significa che lo stato dell'attività (da attivo a distrutto) continua a cambiare a seconda di x motivi. Un'attività dovrebbe essere attiva quando esegui qualcosa su di essa. L'attività è in stato attivo se la sua durata è compresa tra onResume e onPause.
Jayakrishnan

Bene, questo ha senso. Grazie!
Palak Jain

3

Lo uso nel mio frammento.

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;
}

0

Potrebbe essere necessario sostituire getActivity () con MainActivity.this per coloro che hanno problemi con questo.


0

Inizia una nuova attività da un frammento:

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

Inizia una nuova attività da un'attività:

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

0

con Kotlin eseguo questo codice:

requireContext().startActivity<YourTargetActivity>()


Quando provo questo codice ottengo: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 Probabilmente avrai bisogno di Android KTX affinché il codice funzioni.
Edric
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.