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.
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();
}
}
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:
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;
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
}
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;
}
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){}
});
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.
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 .
Et à Kotlin:
tailrec fun Context.activity(): Activity? = when {
this is Activity -> this
else -> (this as? ContextWrapper)?.baseContext?.activity()
}
J'ai utilisé convert Activity
Activity activity = (Activity) context;
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!
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;