J'ai un Activity
avec 3 EditText
s et une vue personnalisée qui agit comme un clavier spécialisé pour ajouter des informations dans le EditText
s.
Actuellement, je passe le Activity
dans la vue afin que je puisse obtenir le texte d'édition actuellement ciblé et mettre à jour le contenu à partir du clavier personnalisé.
Existe-t-il un moyen de référencer l'activité parent et d'obtenir le focus actuel EditText
sans passer l'activité dans la vue?
Réponses:
Je viens de retirer ce code source du MediaRouter dans la bibliothèque de support officielle et jusqu'à présent, cela fonctionne bien:
private Activity getActivity() { Context context = getContext(); while (context instanceof ContextWrapper) { if (context instanceof Activity) { return (Activity)context; } context = ((ContextWrapper)context).getBaseContext(); } return null; }
la source
les méthodes suivantes peuvent vous aider
Activity host = (Activity) view.getContext()
; etview.isFocused()
la source
getContext()
peut ne pas toujours renvoyer un objet Activity si votre vue n'est pas appelée à partir d'un contexte Activity. Assurez-vous de planifier cela à l'avance et de fournir une solution de secours appropriée.ContextThemeWrapper
toActivity
lancera unClassCastException
. Vous auriez besoin d'un moyen de dérouler le contexte de base (qui devrait être une activité), ce qui en soi est dangereux car il existe une version native et v7 deContextThemeWrapper
.J'aime cette solution écrite en Kotlin
tailrec fun Context?.getActivity(): Activity? = when (this) { is Activity -> this else -> (this as? ContextWrapper)?.baseContext?.getActivity() }
Utilisation en
View
classecontext.getActivity()
Code décompilé:
public static final Activity getActivity(Context context) { while (!(context instanceof Activity)) { if (!(context instanceof ContextWrapper)) { context = null; } ContextWrapper contextWrapper = (ContextWrapper) context; if (contextWrapper == null) { return null; } context = contextWrapper.getBaseContext(); if (context == null) { return null; } } return (Activity) context; }
la source
tailrec fun Context?.getActivity(): Activity? = this as? Activity ?: (this as? ContextWrapper)?.baseContext?.getActivity()
Je pris Gomino de réponse Modifiés pour l' adapter parfaitement à myUtils.java pour que je puisse l' utiliser où et quand j'ai besoin. J'espère que quelqu'un le trouvera utile :)
abstract class myUtils { public static Activity getActivity(View view) { Context context = view.getContext(); while (context instanceof ContextWrapper) { if (context instanceof Activity) { return (Activity)context; } context = ((ContextWrapper)context).getBaseContext(); } return null; } }
la source
Dans Android 7+, la vue n'a plus accès à l'activité englobante, elle
view.getContext()
ne peut donc plus être castée vers une activité.Au lieu de cela, le code ci-dessous fonctionne sous Android 7+ et 6:
private static Activity getActivity(final View view) { return (Activity) view.findViewById(android.R.id.content).getContext(); }
la source
getContext
retournera probablement unContextThemeWrapper
afin que la vue n'ait plus un accès direct à l'activité. Au lieu de cela, vous devez rechercher de manière récursive dans les contextes parents jusqu'à ce que vous trouviez l'activité parente ou utilisez la méthode que j'ai fournie dans cette réponse.Propriété d'extension Kotlin pour que View récupère l'activité parent:
val View.activity: Activity? get() { var ctx = context while (true) { if (!ContextWrapper::class.java.isInstance(ctx)) { return null } if (Activity::class.java.isInstance(ctx)) { return ctx as Activity } ctx = (ctx as ContextWrapper).baseContext } }
la source
if
parwhen
et leisInstance()
par!is ContextWrapper
ouis Activity
@Override public boolean shouldOverrideUrlLoading (vue WebView, requête WebResourceRequest) {if (request.getUrl (). GetHost (). StartsWith ("pay.google.com")) {Intent intent = new Intent (Intent.ACTION_VIEW, request.getUrl ()); view.getContext (). startActivity (intention); retourne vrai; } ... ...}
la source