Starten Sie eine Aktivität aus einem Fragment


86

Ich habe 2 Fragmente mit auf beiden Fragmenten einen Knopf. Wenn ich die Taste drücke, möchte ich eine neue Aktivität starten. Aber ich kann es nicht zum Laufen bringen.

Der Fehler, den ich erhalte: FEHLER hier: Typkonflikt: Konvertiert nicht von mFragmentFavorite in Fragment

Was mache ich falsch?

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

Lieblingsaktivität

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

Wenn FavoriteActivity Fragmente erweitert, ist der Fehler verschwunden, aber dann erhalte ich einen Fehler bei findViewById(R.id.mainFavorite);und der Fehler ist

Die Methode findViewById (int) ist für den Typ FavoriteActivity undefiniert

BEARBEITEN:

Wenn ich die Schaltfläche im Fragment drücke, um die Aktivität zu starten, stürzt die App ab. Dies ist mein 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
Vielleicht sollten Sie FragmentActivity nicht erweitern, sondern Fragment?
Spanne

1
Zum einen verwenden Sie nicht Fragments. Zumindest nein in dem Code, den Sie gepostet haben.
Adneal

Antworten:


242

mFragmentFavoriteIn Ihrem Code ist ein, FragmentActivitywas nicht dasselbe ist wie ein Fragment. Das ist der Grund, warum Sie die Typinkongruenz erhalten. Außerdem sollten Sie nie rufen newauf ein Activityals das nicht der richtige Weg ist , einen zu starten.

Wenn Sie eine neue Instanz von starten möchten mFragmentFavorite, können Sie dies über eine Intent.

Aus einem Fragment:

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

Von einem Activity

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

Wenn Sie aFavoritestattdessen starten möchten, mFragmentFavoritemüssen Sie nur deren Namen in der erstellten ändern Intent.

Außerdem empfehle ich, Ihre Klassennamen zu ändern, um genauer zu sein. Etwas mFragmentFavoriteanzurufen ist insofern unangemessen, als es überhaupt kein ist Fragment. Außerdem beginnen Klassendeklarationen in Java normalerweise mit einem Großbuchstaben. Sie sollten Ihre Klasse so benennen FavoriteActivity, dass sie genauer ist und den Sprachkonventionen entspricht. Sie müssen die Datei auch in FavoriteActivity.java umbenennen, wenn Sie dies möchten, da Java erfordert, dass Klassennamen mit dem Dateinamen übereinstimmen.

AKTUALISIEREN

Es sieht auch so aus, als ob Sie eigentlich beabsichtigt hätten mFragmentFavorite, ein Fragmentstatt eines zu sein, FragmentActivitybasierend auf Ihrer Verwendung von onCreateView. Wenn Sie ein sein möchten mFragmentFavorite, Fragmentändern Sie die folgende Codezeile:

public class mFragmentFavorite extends FragmentActivity{

Lassen Sie dies stattdessen lesen:

public class mFragmentFavorite extends Fragment {

Okay, ich werde den Code im ersten Beitrag aktualisieren. Aber ich verstehe die mContextReference nicht ganz. Ich werde den Code mit dem, was ich habe und besseren Namen aktualisieren, geben Sie mir 5 min
mXX

Es ist ein Beispiel für einen Verweis auf ein Fragmentoder ein Activity. Wenn Sie den Code in einer dieser Klassen verwenden, können Sie ihn mContextReferenceentweder getActivity()für Fragmentoder thisfür Activityin der ersten Zeile und thisfür die zweite Zeile ersetzen . Ich werde die Antwort aktualisieren, um klarer zu sein.
Michael Celey

Okay, ich habe die Frage mit besseren Namen und den Ratschlägen, die Sie mir gegeben haben, aktualisiert. Ich werde jetzt versuchen, Ihren Vorschlag umzusetzen, damit er funktioniert. Vielen Dank für die Hilfe
mXX

Ja, ich habe es wieder in Fragment geändert, aber auf dem BTN wird die Fehlermeldung angezeigt, dass die ID "Die Methode findViewById (int) ist für den Typ FavoriteActivity undefiniert"
mXX nicht gefunden wurde

2
Wenn Sie es zu einem machen, Fragmentwechseln Sie findViewByIdzu v.findViewById. Es gibt keine findViewByIdFunktion in, Fragmentalso müssen Sie getViewzuerst aufrufen und dann darauf aufrufen findViewById. In Ihrem Fall haben Sie jedoch bereits Ihre Ansicht in onCreateViewund das wäre Ihre Variable v.
Michael Celey

20

Sie sollten verwenden getActivity(), um Aktivitäten aus Fragmenten zu starten

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

Außerdem sollten Sie Klassen mit Großbuchstaben benennen: MFragmentActivityanstelle von mFragmentActivity.


4

Wenn Sie getActivity () verwenden , müssen Sie sicherstellen, dass die aufrufende Aktivität bereits hinzugefügt wurde . Wenn in einem solchen Fall keine Aktivität hinzugefügt wurde, erhalten Sie möglicherweise null, wenn Sie getActivity () aufrufen.

In solchen Fällen ist getContext () sicher

dann wird der Code zum Starten der Aktivität leicht geändert wie:

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

Aktivität, Service und Anwendung erweitern die ContextWrapper-Klasse, sodass Sie diese oder getContext () oder getApplicationContext () anstelle des ersten Arguments verwenden können.


'Wenn Sie getActivity () verwenden, müssen Sie sicherstellen, dass die aufrufende Aktivität bereits hinzugefügt wurde.' - Was bedeutet diese Zeile für einen Neuling?
Palak Jain

@PalakJain Das bedeutet, dass sich der Status der Aktivität (Aktiv bis Zerstört) abhängig von x Gründen ständig ändert. Eine Aktivität sollte sich im aktiven Zustand befinden, wenn Sie etwas daran ausführen. Die Aktivität befindet sich im aktiven Zustand, wenn ihr Leben zwischen onResume und onPause liegt.
Jayakrishnan

Nun, das macht Sinn. Vielen Dank!
Palak Jain

3

Ich benutze dies in meinem 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;
}

0

Möglicherweise müssen Sie getActivity () durch MainActivity ersetzen. Dies ist für diejenigen, die Probleme damit haben.


0

Neue Aktivität aus einem Fragment starten:

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

Neue Aktivität aus einer Aktivität starten:

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.