Iniciar una actividad desde un fragmento

91

Tengo 2 fragmentos con en ambos fragmentos un botón. Cuando presiono el botón, me gustaría iniciar una nueva actividad. Pero no puedo hacer que funcione.

El error que recibo: ERROR aquí: no coinciden los tipos: no se puede convertir de mFragmentFavorite a Fragment

¿Qué estoy haciendo 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;
    }
}

Actividad favorita

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 extiende fragmentos, el error desaparece, pero luego aparece un error en findViewById(R.id.mainFavorite);y el error es

El método findViewById (int) no está definido para el tipo FavoriteActivity

EDITAR:

Cuando presiono el botón en el fragmento para iniciar la actividad, la aplicación se bloquea, este es mi 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
fuente
3
¿Quizás no deberías extender FragmentActivity sino Fragment?
abarcará el
1
Bueno, para uno que no estás usando Fragments. Al menos no en el código que publicaste.
adneal

Respuestas:

247

mFragmentFavoriteen su código es un FragmentActivityque no es lo mismo que un Fragment. Es por eso que aparece la falta de coincidencia de tipos. Además, nunca debe recurrir newa una Activityya que esa no es la forma correcta de iniciar una.

Si desea iniciar una nueva instancia de mFragmentFavorite, puede hacerlo mediante un archivo Intent.

De un Fragment:

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

Desde un Activity

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

Si desea comenzar en aFavoritelugar de mFragmentFavorite, solo necesita cambiar sus nombres en el archivo creado Intent.

Además, recomiendo cambiar los nombres de las clases para que sean más precisos. Llamar a algo mFragmentFavoritees inapropiado en el sentido de que no lo es Fragmenten absoluto. Además, las declaraciones de clase en Java suelen comenzar con una letra mayúscula. Haría bien en nombrar su clase de una manera FavoriteActivitymás precisa y conforme a las convenciones del idioma. También deberá cambiar el nombre del archivo a FavoriteActivity.java si elige hacerlo, ya que Java requiere que los nombres de clase coincidan con el nombre del archivo.

ACTUALIZAR

Además, parece que en realidad pretendías mFragmentFavoriteser un en Fragmentlugar de un FragmentActivitysegún tu uso de onCreateView. Si quieres mFragmentFavoriteser un Fragment, cambia la siguiente línea de código:

public class mFragmentFavorite extends FragmentActivity{

Haga que esto en su lugar lea:

public class mFragmentFavorite extends Fragment {
Michael Celey
fuente
De acuerdo, actualizaré el código en la primera publicación. Pero no entiendo bien el mContextReference. Actualizaré el código con lo que tengo y mejores nombres, dame 5 min
mXX
Es un ejemplo de referencia a un Fragmento un Activity. Si está utilizando el código dentro de una de esas clases, puede reemplazarlo mContextReferencecon getActivity()for Fragmento thisfor Activityen la primera línea y thisen la segunda línea. Actualizaré la respuesta para que sea más clara.
Michael Celey
De acuerdo, actualicé la pregunta con mejores nombres y los consejos que me diste. Ahora intentaré implementar su sugerencia para intentar que funcione. Gracias por la ayuda
mXX
Sí, lo cambié de nuevo a Fragmento pero aparece el error en el btn para encontrar el ID "El método findViewById (int) no está definido para el tipo FavoriteActivity"
mXX
2
Si lo hace, Fragmentcambie findViewByIda v.findViewById. No hay findViewByIdfunción en, Fragmentpor lo que debe llamar getViewprimero y luego llamar findViewByIda eso. Sin embargo, en su caso, ya tiene su vista onCreateViewy esa sería su variable v.
Michael Celey
21

Deberías usar getActivity()para lanzar actividades desde fragmentos

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

Además, debería nombrar las clases con mayúsculas: en MFragmentActivitylugar de mFragmentActivity.

mentiroso
fuente
4

Si está utilizando getActivity () , debe asegurarse de que la actividad de llamada ya esté agregada . Si no se ha agregado actividad en tal caso, puede obtener un valor nulo cuando llame a getActivity ()

en tales casos, getContext () es seguro

entonces el código para iniciar la actividad cambiará ligeramente como,

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

La actividad, el servicio y la aplicación amplían la clase ContextWrapper para que pueda usar esto o getContext () o getApplicationContext () en lugar del primer argumento.

Jayakrishnan
fuente
'Si está utilizando getActivity (), entonces debe asegurarse de que la actividad de llamada ya esté agregada'. ¿Qué significa esta línea para un novato?
Palak Jain
@PalakJain Eso significa que el estado de la actividad (activo a destruido) sigue cambiando dependiendo de x razones. Una actividad debe estar en estado activo cuando realiza algo en ella. La actividad está en estado activo si su vida está entre onResume y onPause.
Jayakrishnan
Bueno, eso tiene sentido. ¡Gracias!
Palak Jain
3

Yo uso esto en mi fragmento.

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
fuente
0

Puede que tenga que reemplazar getActivity () con MainActivity.this para aquellos que tienen problemas con esto.

ADL
fuente
0

Iniciar una nueva actividad desde un fragmento:

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

Iniciar una nueva actividad desde una actividad:

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

con Kotlin ejecuto este código:

requireContext().startActivity<YourTargetActivity>()

Alexandr Kolesnik
fuente
Cuando intento este código obtengo: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 Probablemente necesitará Android KTX para que el código funcione.
Edric