web-dev-qa-db-fra.com

Obtenir de l'activité du contexte dans Android

Celui-ci m'a laissé perplexe.

J'ai besoin d'appeler une méthode d'activité depuis une classe de présentation personnalisée. Le problème, c'est que je ne sais pas comment accéder à l'activité depuis la mise en page.

ProfileView

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

ProfilActivité

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

Comme vous pouvez le voir ci-dessus, je suis en train d'instancier le programme profileView et de lui transmettre le champ activityContext. 2 questions:

  1. Suis-je en train de passer le bon contexte dans Profileview?
  2. Comment puis-je obtenir l'activité contenant du contexte?
149
OVERTONE

A partir de votre Activity, indiquez simplement this en tant que Context pour votre mise en page:

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

Ensuite, vous aurez une Context dans la mise en page, mais vous saurez que c’est en fait votre Activity et vous pouvez la lancer de sorte que vous ayez ce dont vous avez besoin:

Activity activity = (Activity) context;
420
Boris Strandjev
  1. Non
  2. Vous ne pouvez pas

Il existe deux contextes différents dans Android. Un pour votre application (appelons-le le grand) et un pour chaque vue (appelons-le le contexte de l'activité).

LinearLayout est une vue, vous devez donc appeler le contexte de l'activité. Pour l'appeler d'une activité, appelez simplement "ceci". Si facile n'est-ce pas?

Quand vous utilisez

this.getApplicationContext();

Vous appelez le contexte BIG, celui qui décrit votre application et ne peut pas gérer votre vue.

Un gros problème avec Android est qu’un contexte ne peut pas appeler votre activité. C'est un gros problème à éviter lorsque quelqu'un commence par le développement d'Android. Vous devez trouver un meilleur moyen de coder votre classe (ou remplacer "Contexte du contexte" par "Activité" et le convertir en "Contexte" si nécessaire).

Cordialement.


Juste pour mettre à jour ma réponse. Le moyen le plus simple d’obtenir votre Activity context est de définir une instance static dans votre Activity. Par exemple

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

Et puis, dans votre Task, Dialog, View, vous pourriez utiliser ce type de code pour obtenir votre Activity context:

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

C’est quelque chose que j’ai utilisé avec succès pour convertir Context en Activity lorsqu’il fonctionne dans l’interface utilisateur en fragments ou en vues personnalisées. Il décompressera ContextWrapper de manière récursive ou renverra null s'il échoue.

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

Si vous souhaitez appeler une méthode d'activité depuis une classe de présentation personnalisée (non-classe d'activité), vous devez créer un délégué à l'aide de l'interface. 

Il n'a pas été testé et je l'ai bien codé. mais je transmets un moyen d'atteindre ce que vous voulez.

Tout d'abord créer et 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");
    }
}

Et implémentez ceci dans n'importe quelle activité.

et l'appelle comme

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

Le contexte peut être une application, un service, une activité, etc.

Normalement, le contexte des vues dans une activité est l'activité elle-même; vous pouvez donc penser que vous pouvez simplement transtyper ce contexte en activité, mais en réalité vous ne pouvez pas toujours le faire, car le contexte peut également être un contexteThemeWrapper dans ce cas.

ContextThemeWrapper est très utilisé dans les versions récentes d'AppCompat et Android (grâce à l'attribut Android: theme dans les mises en page), donc personnellement, je ne ferais jamais ce casting.

La réponse est très courte: vous ne pouvez pas récupérer de manière fiable une activité à partir d'un contexte dans une vue. Passez l'activité à la vue en appelant une méthode qui prend l'activité en tant que paramètre.

6
BladeCoder

N'utilisez jamais (getApplicationContext ()) avec des vues.

Il doit toujours s'agir du contexte de l'activité, car la vue est attachée à l'activité. En outre, vous pouvez avoir un ensemble de thèmes personnalisé et, lors de l'utilisation du contexte de l'application, toutes les thématiques seront perdues. En savoir plus sur les différentes versions de contextes ici .

2
lomza

Et à Kotlin:

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

J'ai utilisé convert Activity

Activity activity = (Activity) context;
0
Samuel Ivan

Cette méthode devrait être utile ..!

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;

    }

J'espère que cela aide .. Joyeux codage!

0
Taslim Oseni

une activité est une spécialisation de contexte. Par conséquent, si vous avez un contexte, vous savez déjà quelle activité vous souhaitez utiliser et vous pouvez simplement transtyperaenc; oùaest une activité etcest un contexte.

Activity a = (Activity) c;
0
ACLima