Android support library 23.4.0: android.de soutien.v7.widget de.TintContextWrapper ne peut pas être lancé à l'Activité
J'ai donc mis à jour pour la dernière bibliothèques de prise en charge, et a obtenu un crash je ne suis pas en mesure de corriger. Mon build.gradle maintenant a ces dépendances:
dependencies {
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:gridlayout-v7:23.4.0'
compile 'com.android.support:support-v4:23.4.0'
compile 'com.android.support:cardview-v7:23.4.0'
compile 'com.android.support:recyclerview-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
//More stuff...
}
J'ai eu un travail de l'auditeur qui est utilisé pour intercepter les clics et commencez une nouvelle Activité. Cela fonctionnait bien dans les bibliothèques de prise en charge v. 23.1.0, mais pas dans 23.4.0 (et 23.3.0):
public class IngredientItemOnClickListener implements OnClickListener
{
private Ingredient mIngredient;
public IngredientItemOnClickListener(Ingredient ingredient)
{
mIngredient= ingredient;
}
@Override
public void onClick(View view)
{
MyActivity myActivity = (MyActivity) view.getContext(); //<-- crash here
myActivity.showIngredientActivity(mIngredient);
}
}
Cet écouteur est simplement attaché à un ImageButton
et, par la suite, la couleur du Bouton est teinté, comme ceci:
Ingredient ingredient = getIngredient();
myImageButton.setOnClickListener(new IngredientItemOnClickListener(ingredient));
Drawable drawable = Tinting.tint(myActivity, R.drawable.my_icon, R.color.red);
myImageButton.setImageDrawable(drawable);
où Tinting.tint()
est mon propre teinte de la fonction:
public class Tinting
{
@Nullable
public static Drawable tint(Context context, int drawableId, int colorId)
{
final Drawable drawable = ContextCompat.getDrawable(context, drawableId);
if (drawable != null)
{
final Drawable wrapped = DrawableCompat.wrap(drawable);
drawable.mutate();
DrawableCompat.setTint(wrapped, ContextCompat.getColor(context, colorId));
}
return drawable;
}
}
Précédemment lorsque j'ai cliqué sur le bouton tout a fonctionné comme prévu, mais aujourd'hui le Contexte du point de Vue semble avoir changé de TintContextWrapper
qui je trouve peu d'informations sur. J'ai trouvé ce problème, mais le projet de membre conseille de demander ici sur StackOverflow, si elle est ici.
Qu'ai-je essayé?
Depuis le projet de membre dans le Google question Vous aurez besoin d'obtenir l'activité de la enveloppé contexte. J'ai essayé de casting pour TintContextWrapper
au lieu de MyActivity
, qui fonctionne très bien, mais je ne peux pas comprendre comment obtenir MyActivity
de TintContextWrapper
.
Donc mes questions sont:
- Comment puis-je obtenir
MyActivity
de laTintContextWrapper
? - Pourquoi mon
ImageButton
soudain enveloppé dans unTintContextWrapper
. - Si ce comportement vraiment attendre?
Définition de ImageButton en xml est tout simplement:
<ImageButton
android:id="@+id/my_id"
android:src="@drawable/my_icon" />
Trace de la pile:
java.lang.ClassCastException: android.support.v7.widget.TintContextWrapper cannot be cast to com.my.app.activities.MyActivity
at com.my.app.listeners.IngredientItemOnClickListener.onClick(IngredientItemOnClickListener.java:21)
at android.view.View.performClick(View.java:4475)
at android.view.View$PerformClick.run(View.java:18786)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
at dalvik.system.NativeStart.main(Native Method)
MyItemOnClickListener
. Où est-il ?Désolé, il y a une erreur de mon côté, je mets à jour la trace de la pile. Le crash est dans
IngredientItemOnClickListener
qui est fixé dans la question.
OriginalL'auteur Krøllebølle | 2016-05-12
Vous devez vous connecter pour publier un commentaire.
la fois de l'activité n TintContextWRapper vient de
ContextWrapper
.ContextWrapper
avoir une méthodegetBaseContext()
. Il devrait être facile de créer une méthode de boucle qui vérifieinstanceof WrapContext
, obtient de la base de contexte et vérifie ensuiteinstanceof Activity
. (Si vous avez des problèmes avec cette méthode commentaire ici que je vais creuser un projet de mine et coller ici à u)Parce que AppCompat enveloppe votre contexte afin de pouvoir injecter "compat" points de vue et "compact" de teinture et d'autres "compat" choses". C'est normal.
Oui. C'est comment AppCompat fait sa chose.
ContextWrapper
classes fonctionné et pourquoi.Le code de la "méthode de boucle qui vérifie instanceof WrapContext" peut être trouvé ici: stackoverflow.com/a/32973351
OriginalL'auteur Budius
@Krøllebølle
Répondre à votre question, c'est :
le premier de votre événement click code devrait ressembler à:
et puis écrire la fonction getRequiredActivity():
et votre Crash/Exception est corrigé 🙂
OriginalL'auteur Nitesh Jha
Ma suggestion est de passer une référence de votre activité dans le onClickListener pour éviter le problème avec
TintContextWrapper
. Donner à votre classe une référence àMyActivity
est simple et évite de casting questions.OriginalL'auteur Fire3galaxy
Vous pouvez essayer
Obtient le contexte qui contient ce point de vue, sans l'emballage d'android.de soutien.v7.widget de.TintContextWrapper.
OriginalL'auteur yeberiah
Vous ne devriez vraiment pas. Il n'y a aucune garantie qu'une Vue du Contexte sera une Activité -- certainement pas une Activité spécifique. Où en êtes-vous de la définition de votre OnClickListener? Je suis en supposant qu'à l'endroit où vous définissez le port d'écoute, vous aurez accès à l'Activité. Par exemple, si l'auditeur à partir d'une Activité:
Je dirais que c'est "pas la bonne chose". Ça peut fonctionner, mais il n'y a rien dans l'API qui garantit qu'elle ne cassera pas encore dans une autre bibliothèque. Pour votre cas, je vous recommande l'ajout d'une interface pour votre RecyclerView (quelque chose comme OnIngredientClickedListener) et d'un fournisseur à un setter que votre Activité est susceptible de fournir une instance de. Ensuite, private OnClickListener dans le RecyclerView qui fera suivre les clics jusqu'à la OnIngredientClickedListener. Qui supprime votre dépendance matérielle sur MainActivity.
Approche intéressante. Je vais essayer de faire quelque chose comme ça et dans quelques autres endroits dans mon code. Il est intéressant de noter, cependant, que le projet de membre dans question vous conseillons l'Activité de la enveloppé contexte. Cette personne pourrait être "trompé" bien sûr.
OriginalL'auteur kcoppock
Il a travaillé pour moi après la mise à jour Android Bibliothèques de prise en charge.
OriginalL'auteur razmik
J'ai connu le même problème et résolu
- Android Support Library, la révision de l'article 24.2.1 (septembre 2016)
- compileSdkVersion 24
- buildToolsVersion "24.0.3"
OriginalL'auteur Amol