it-swarm.com.de

Aktivität aus dem Kontext in Android abrufen

Dieser hat mich verblüfft.

Ich muss eine Aktivitätsmethode aus einer benutzerdefinierten Layoutklasse aufrufen. Das Problem dabei ist, dass ich nicht weiß, wie ich vom Layout aus auf die Aktivität zugreifen kann.

Profilansicht

public class ProfileView extends LinearLayout
{
    TextView profileTitleTextView;
    ImageView profileScreenImageButton;
    boolean isEmpty;
    ProfileData data;
    String name;

    public ProfileView(Context context, AttributeSet attrs, String name, final ProfileData profileData)
    {
        super(context, attrs);
        ......
        ......
    }

    //Heres where things get complicated
    public void onClick(View v)
    {
        //Need to get the parent activity and call its method.
        ProfileActivity x = (ProfileActivity) context;
        x.activityMethod();
    }
}

ProfilAktivität

public class ProfileActivityActivity extends Activity
{
    //In here I am creating multiple ProfileViews and adding them to the activity dynamically.

    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.profile_activity_main);
    }

    public void addProfilesToThisView()
    {
        ProfileData tempPd = new tempPd(.....)
        Context actvitiyContext = this.getApplicationContext();
        //Profile view needs context, null, name and a profileData
        ProfileView pv = new ProfileView(actvitiyContext, null, temp, tempPd);
        profileLayout.addView(pv);
    }
}

Wie Sie oben sehen können, instantiiere ich die profileView programmatisch und gebe den ActivityContext damit weiter. 2 Fragen:

  1. Übergebe ich den richtigen Kontext in die Profilansicht?
  2. Wie bekomme ich die enthaltene Aktivität aus dem Kontext?
149
OVERTONE

Übergeben Sie in Ihrer Activity einfach this als Context für Ihr Layout:

ProfileView pv = new ProfileView(this, null, temp, tempPd);

Danach haben Sie eine Context im Layout, aber Sie wissen, dass es sich tatsächlich um Ihre Activity handelt, und Sie können sie so umsetzen, dass Sie das bekommen, was Sie brauchen:

Activity activity = (Activity) context;
420
Boris Strandjev
  1. Nein
  2. Du kannst nicht

Es gibt zwei verschiedene Kontexte in Android. Eine für Ihre Anwendung (nennen wir sie die GROSSE) und eine für jede Ansicht (nennen wir sie den Aktivitätskontext).

Ein lineares Layout ist eine Ansicht, daher müssen Sie den Aktivitätskontext aufrufen. Um von einer Aktivität aus aufzurufen, rufen Sie einfach "this" auf. So einfach ist es nicht?

Wenn Sie verwenden

this.getApplicationContext();

Sie rufen den BIG-Kontext auf, der Ihre Anwendung beschreibt, und können Ihre Ansicht nicht verwalten.

Ein großes Problem bei Android ist, dass ein Kontext Ihre Aktivität nicht aufrufen kann. Das ist eine große Sache, um dies zu vermeiden, wenn jemand mit der Android-Entwicklung beginnt. Sie müssen einen besseren Weg finden, Ihre Klasse zu codieren (oder "Kontextkontext" durch "Aktivitätsaktivität" ersetzen und bei Bedarf in "Kontext" umwandeln).

Grüße.


Nur um meine Antwort zu aktualisieren. Der einfachste Weg, Ihren Activity context zu erhalten, besteht darin, eine static-Instanz in Ihrer Activity zu definieren. Zum Beispiel

public class DummyActivity extends Activity
{
    public static DummyActivity instance = null;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        // Do some operations here
    }

    @Override
    public void onResume()
    {
        super.onResume();
        instance = this;
    }

    @Override
    public void onPause()
    {
        super.onPause();
        instance = null;
    }
}

Und dann könnten Sie in Ihrer Task, Dialog, View diesen Code verwenden, um Ihren Activity context zu erhalten:

if (DummyActivity.instance != null)
{
    // Do your operations with DummyActivity.instance
}
24
Manitoba

Dies ist etwas, das ich erfolgreich verwendet habe, um Context in Activity zu konvertieren, wenn ich innerhalb der Benutzeroberfläche in Fragmenten oder benutzerdefinierten Ansichten arbeite. Es wird ContextWrapper rekursiv entpackt oder zurückgegeben, wenn es fehlschlägt.

public Activity getActivity(Context context)
{
    if (context == null)
    {
        return null;
    }
    else if (context instanceof ContextWrapper)
    {
        if (context instanceof Activity)
        {
            return (Activity) context;
        }
        else
        {
            return getActivity(((ContextWrapper) context).getBaseContext());
        }
    }

    return null;
}
23
Theo

Wenn Sie eine Aktivitätsmethode innerhalb einer benutzerdefinierten Layoutklasse (Nicht-Aktivitätsklasse) aufrufen möchten. Sie sollten einen Delegaten mithilfe der Schnittstelle erstellen. 

Es ist nicht getestet und ich habe es richtig codiert. aber ich vermittle einen Weg, um das zu erreichen, was Sie wollen.

Zunächst einmal erstellen und Interface 

interface TaskCompleteListener<T> {
   public void onProfileClicked(T result);
}



public class ProfileView extends LinearLayout
{
    private TaskCompleteListener<String> callback;
    TextView profileTitleTextView;
    ImageView profileScreenImageButton;
    boolean isEmpty;
    ProfileData data;
    String name;

    public ProfileView(Context context, AttributeSet attrs, String name, final ProfileData profileData)
    {
        super(context, attrs);
        ......
        ......
    }
    public setCallBack( TaskCompleteListener<String> cb) 
    {
      this.callback = cb;
    }
    //Heres where things get complicated
    public void onClick(View v)
    {
        callback.onProfileClicked("Pass your result or any type");
    }
}

Und implementiere dies für jede Aktivität.

und nennen es gerne

ProfileView pv = new ProfileView(actvitiyContext, null, temp, tempPd);
pv.setCallBack(new TaskCompleteListener
               {
                   public void onProfileClicked(String resultStringFromProfileView){}
               });
7
Xar E Ahmer

Der Kontext kann eine Anwendung, ein Dienst, eine Aktivität und mehr sein.

Normalerweise ist der Kontext von Ansichten in einer Aktivität die Aktivität selbst. Sie denken also, dass Sie diesen Kontext einfach in Aktivität umwandeln können, aber Sie können dies nicht immer tun, da der Kontext in diesem Fall auch ein ContextThemeWrapper sein kann.

ContextThemeWrapper wird in den letzten Versionen von AppCompat und Android stark verwendet (dank des Attributs Android: theme in Layouts). Daher würde ich diesen Cast niemals persönlich durchführen.

Die Antwort ist kurz: Sie können eine Aktivität nicht zuverlässig aus einem Kontext in einer Ansicht abrufen. Übergeben Sie die Aktivität an die Ansicht, indem Sie eine Methode für die Ansicht aufrufen, die die Aktivität als Parameter übernimmt.

6
BladeCoder

Verwenden Sie niemals getApplicationContext () mit Ansichten.

Es sollte immer der Kontext der Aktivität sein, da die Sicht an die Aktivität gebunden ist. Möglicherweise haben Sie auch ein benutzerdefiniertes Design, und wenn Sie den Anwendungskontext verwenden, gehen alle Themen verloren. Lesen Sie mehr über verschiedene Versionen von Kontexten hier .

2
lomza

Und in Kotlin:

tailrec fun Context.activity(): Activity? = when {
  this is Activity -> this
  else -> (this as? ContextWrapper)?.baseContext?.activity()
}
0
rjrjr

Ich habe convert Activity verwendet

Activity activity = (Activity) context;
0
Samuel Ivan

Diese Methode sollte hilfreich sein ..!

public Activity getActivityByContext(Context context){

if(context == null){
    return null;
    }

else if((context instanceof ContextWrapper) && (context instanceof Activity)){
        return (Activity) context;
    }

else if(context instanceof ContextWrapper){
        return getActivity(((ContextWrapper) context).getBaseContext());
    }

return null;

    }

Ich hoffe das hilft. Fröhliche Kodierung!

0
Taslim Oseni

eine Aktivität ist eine Spezialisierung von Kontext. Wenn Sie also einen Kontext haben, wissen Sie bereits, welche Aktivität Sie verwenden möchten, und Sie können a in c; Dabei ist a eine Aktivität und c ein Kontext.

Activity a = (Activity) c;
0
ACLima