Comece uma atividade a partir de um fragmento

92

Eu tenho 2 fragmentos com em ambos os fragmentos um botão. Quando pressiono o botão, gostaria de iniciar uma nova atividade. Mas não consigo fazer funcionar.

Estou recebendo o erro : ERROR here: Type mismatch: não é possível converter de mFragmentFavorite para Fragment

O que estou fazendo errado?

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

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

Se FavouriteActivity estende fragmentos, o erro desaparece, mas recebo um erro em findViewById(R.id.mainFavorite);e o erro é

O método findViewById (int) é indefinido para o tipo FavoriteActivity

EDITAR:

Quando pressiono o botão no fragmento para iniciar a atividade, o aplicativo trava, este é o meu 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
fonte
3
Talvez você não deva estender FragmentActivity, mas sim Fragment?
período de
1
Bem, para quem você não está usando Fragments. Pelo menos não no código que você postou.
adneal de

Respostas:

252

mFragmentFavoriteem seu código está a FragmentActivityque não é a mesma coisa que a Fragment. É por isso que você está obtendo a incompatibilidade de tipo. Além disso, você nunca deve ligar newpara um, Activitypois essa não é a maneira correta de iniciar um.

Se você deseja iniciar uma nova instância de mFragmentFavorite, pode fazê-lo por meio de um Intent.

De um Fragment:

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

De um Activity

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

Se você quiser começar em aFavoritevez de mFragmentFavoriteentão você só precisa mudar seus nomes no criado Intent.

Além disso, recomendo alterar os nomes das classes para ser mais preciso. Chamar algo mFragmentFavoriteé impróprio porque não é um Fragment. Além disso, as declarações de classe em Java geralmente começam com uma letra maiúscula. Você faria bem em nomear sua classe FavoriteActivityde forma mais precisa e em conformidade com as convenções de idioma. Você também precisará renomear o arquivo para FavoriteActivity.java se optar por fazer isso, pois o Java requer que os nomes das classes correspondam ao nome do arquivo.

ATUALIZAR

Além disso, parece que você realmente pretendia mFragmentFavoriteser um em Fragmentvez de com FragmentActivitybase no uso de onCreateView. Se você quiser mFragmentFavoriteser um Fragment, altere a seguinte linha de código:

public class mFragmentFavorite extends FragmentActivity{

Em vez disso, faça com que leia:

public class mFragmentFavorite extends Fragment {
Michael Celey
fonte
Ok, vou atualizar o código no primeiro post. Mas eu não entendo muito bem o mContextReference. Vou atualizar o código com o que tenho e melhores nomes, dê-me 5 min
mXX
É um exemplo de referência a um Fragmentou um Activity. Se você estiver usando o código dentro de uma dessas classes, você pode simplesmente substituir mContextReferencepor getActivity()for Fragmentou thisfor Activityna primeira linha e thisna segunda linha. Vou atualizar a resposta para ser mais claro.
Michael Celey
Ok, atualizei a pergunta com nomes melhores e os conselhos que você me deu. Vou tentar agora implementar sua sugestão para tentar fazê-la funcionar. Obrigado pela ajuda
mXX
Sim, mudei de volta para Fragment, mas recebo o erro no btn para encontrar o ID "O método findViewById (int) é indefinido para o tipo FavoriteActivity"
mXX
2
Se você definir um, Fragmententão mude findViewByIdpara v.findViewById. Não há nenhuma findViewByIdfunção em, Fragmententão você tem que chamar getViewprimeiro e depois chamá findViewById-la. No seu caso, porém, você já tem sua visão onCreateViewe essa seria sua variável v.
Michael Celey
21

Você deve usar getActivity()para lançar atividades a partir de fragmentos

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

Além disso, você deve nomear classes com maiúsculas: em MFragmentActivityvez de mFragmentActivity.

mentiroso
fonte
4

Se você estiver usando getActivity () , certifique-se de que a atividade de chamada já tenha sido adicionada . Se a atividade não foi adicionada nesse caso, você pode obter nulo ao chamar getActivity ()

nesses casos getContext () é seguro

então o código para iniciar a atividade será ligeiramente alterado como,

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

Activity, Service and Application estendem a classe ContextWrapper para que você possa usar this ou getContext () ou getApplicationContext () no lugar do primeiro argumento.

Jayakrishnan
fonte
'Se você estiver usando getActivity (), certifique-se de que a atividade de chamada já foi adicionada.' - O que esta linha significa para um novato?
Palak Jain de
@PalakJain Isso significa que o estado da atividade (Ativo para Destruído) continua mudando dependendo de x razões. Uma atividade deve estar no estado ativo quando você executa qualquer coisa nela. A atividade está no estado ativo se sua duração estiver entre onResume e onPause.
Jayakrishnan
Bem, isso faz sentido. Obrigado!
Palak Jain
3

Eu uso isso no meu 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
fonte
1

Inicie uma nova atividade a partir de um fragmento:

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

Iniciar nova atividade a partir de uma atividade:

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

Pode ser necessário substituir getActivity () por MainActivity.this para aqueles que estão tendo problemas com isso.

ADL
fonte
0

com Kotlin eu executo este código:

requireContext().startActivity<YourTargetActivity>()

Alexandr Kolesnik
fonte
Quando tento este código, recebo: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 Você provavelmente precisará do Android KTX para que o código funcione.
Edric