Rozpocznij ćwiczenie od fragmentu


91

Mam 2 fragmenty z przyciskiem na obu fragmentach. Po naciśnięciu przycisku chcę rozpocząć nowe działanie. Ale nie mogę zmusić tego do pracy.

Błąd, który otrzymuję: BŁĄD tutaj: Niezgodność typu: nie można przekonwertować z mFragmentFavorite na fragment

Co ja robię źle?

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

Ulubiona aktywność

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

Jeśli FavouriteActivity rozszerza fragmenty, błąd zniknął, ale pojawia się błąd w miejscu findViewById(R.id.mainFavorite);i błąd jest

Metoda findViewById (int) jest niezdefiniowana dla typu FavoriteActivity

EDYTOWAĆ:

Kiedy naciskam przycisk we fragmencie, aby rozpocząć działanie, aplikacja ulega awarii, to jest mój 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
Może nie powinieneś rozszerzać FragmentActivity, ale raczej Fragment?
obejmuje okres

1
Cóż, na przykład, którego nie używasz Fragments. Przynajmniej nie w opublikowanym kodzie.
adneal

Odpowiedzi:


247

mFragmentFavoritew twoim kodzie jest a, FragmentActivityktóry nie jest tym samym co Fragment. Dlatego otrzymujesz niezgodność typu. Ponadto nigdy nie powinieneś dzwonić newnaActivity ponieważ nie jest to właściwy sposób na rozpoczęcie.

Jeśli chcesz rozpocząć nową instancję programu mFragmentFavorite, możesz to zrobić za pomocą pliku Intent.

Od Fragment:

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

Z Activity

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

Jeśli chcesz aFavoritezamiast tego zacząć mFragmentFavorite, wystarczy zmienić ich nazwy w utworzonym Intent.

Zalecam również zmianę nazw klas, aby były dokładniejsze. Nazywanie czegoś mFragmentFavoritejest niewłaściwe, ponieważ wcale nie jest Fragment. Ponadto deklaracje klas w Javie zwykle zaczynają się od dużej litery. Dobrze by było, gdybyś nazwał swoją klasę FavoriteActivitybardziej precyzyjną i zgodną z konwencjami językowymi. Jeśli zdecydujesz się to zrobić, musisz również zmienić nazwę pliku na FavoriteActivity.java, ponieważ Java wymaga, aby nazwy klas pasowały do ​​nazwy pliku.

AKTUALIZACJA

Wygląda też na to, że faktycznie chciałeś mFragmentFavoritebyć a Fragmentzamiast a FragmentActivityna podstawie tego, jak używasz onCreateView. Jeśli chcesz mFragmentFavoritebyć Fragmenta, zmień następujący wiersz kodu:

public class mFragmentFavorite extends FragmentActivity{

Zrób to zamiast tego przeczytaj:

public class mFragmentFavorite extends Fragment {

OK, zaktualizuję kod w pierwszym poście. Ale nie całkiem rozumiem mContextReference. Zaktualizuję kod o to, co mam i lepsze nazwy, daj mi 5 minut
mXX

To przykład odwołania do a Fragmentlub an Activity. Jeśli używasz kodu wewnątrz jednej z tych klas, możesz po prostu zamienić mContextReferencena getActivity()for Fragmentlub thisfor Activityw pierwszej linii i thisdrugiej linii. Zaktualizuję odpowiedź, aby była bardziej przejrzysta.
Michael Celey,

OK, zaktualizowałem pytanie o lepsze nazwy i porady, które mi dałeś. Spróbuję teraz wdrożyć twoją sugestię, żeby to zadziałało. Dzięki za pomoc
mXX

Tak, zmieniłem go z powrotem na Fragment, ale pojawia się błąd w btn, aby znaleźć identyfikator „Metoda findViewById (int) jest niezdefiniowana dla typu FavoriteActivity”
mXX

2
Jeśli to zrobisz, Fragmentzmień findViewByIdna v.findViewById. Nie ma findViewByIdfunkcji, Fragmentwięc musisz getViewnajpierw zadzwonić, a następnie to wywołać findViewById. Jednak w twoim przypadku masz już swój widok onCreateViewi to byłaby twoja zmienna v.
Michael Celey

21

Powinieneś użyć getActivity()do uruchamiania działań z fragmentów

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

Powinieneś także nazywać klasy kapitalikami: MFragmentActivityzamiast mFragmentActivity.


4

Jeśli używasz getActivity () , musisz się upewnić, że aktywność wywołująca została już dodana . Jeśli aktywność nie została dodana w takim przypadku, więc możesz uzyskać wartość null po wywołaniu metody getActivity ()

w takich przypadkach getContext () jest bezpieczna

wtedy kod do uruchomienia działania zostanie nieco zmieniony, np.

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

Aktywność, usługa i aplikacja rozszerzają klasę ContextWrapper, dzięki czemu można użyć metody this lub getContext () lub getApplicationContext () zamiast pierwszego argumentu.


„Jeśli używasz metody getActivity (), musisz upewnić się, że aktywność wywołująca została już dodana.” - Co ta linia oznacza dla początkującego?
Palak Jain

@PalakJain Oznacza to, że stan aktywności (od aktywnej do zniszczonej) zmienia się w zależności od x powodów. Aktywność powinna być aktywna, gdy cokolwiek na niej wykonujesz. Aktywność jest w stanie aktywnym, jeśli jej życie jest między onResume a onPause.
Jayakrishnan

Cóż, to ma sens. Dzięki!
Palak Jain

3

Używam tego w moim fragmencie.

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

Być może będziesz musiał zamienić getActivity () na MainActivity.this dla tych, którzy mają z tym problemy.


0

Rozpocznij nową aktywność od fragmentu:

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

Rozpocznij nowe działanie od działania:

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

0

z Kotlinem wykonuję ten kod:

requireContext().startActivity<YourTargetActivity>()


Kiedy próbuję tego kodu, otrzymuję: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 Prawdopodobnie będziesz potrzebować Androida KTX , aby kod działał.
Edric
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.