Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Librería de soporte de Android 23.4.0: android.support.v7.widget.TintContextWrapper no se puede publicar en Actividad

Así que me actualizé a las últimas bibliotecas de soporte, y recibí un fallo que no puedo arreglar. Mi build.gradle ahora tiene estas dependencias:

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

Tuve un oyente de trabajo que se utiliza para capturar clics y comenzar una nueva actividad. Esto funcionaba bien en bibliotecas de soporte v. 23.1.0, pero no en 23.4.0 (y 23.3.0):

  • Cómo detectar los bordes largos de la pared para preparar la máscara y recolorar
  • ¿Cómo mantengo un Servicio vivo indefinidamente?
  • Cómo centralizar el diseño dentro de Android Dialog?
  • Configuración de RelativeLayout en código java
  • Cómo hacer que TextView se pueda desplazar en Android
  • ¿Es posible que VM de Android recolecte basura de variables estáticas sin matar a toda la aplicación de Android?
  •  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); } } 

    Este oyente está simplemente conectado a un ImageButton y después el color del botón está tintado, como este:

     Ingredient ingredient = getIngredient(); myImageButton.setOnClickListener(new IngredientItemOnClickListener(ingredient)); Drawable drawable = Tinting.tint(myActivity, R.drawable.my_icon, R.color.red); myImageButton.setImageDrawable(drawable); 

    Donde Tinting.tint() es mi propia función de teñido:

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

    Anteriormente cuando hice clic en el botón todo funcionó como se esperaba, pero ahora el contexto de la vista parece haber cambiado a TintContextWrapper que puedo encontrar poca información sobre. Encontré este problema , pero el miembro del proyecto aconseja preguntar aquí en StackOverflow, así que aquí está.

    ¿Qué he intentado?

    Dado que el miembro del proyecto en el problema de Google declaró que tendrá que obtener la actividad del contexto envuelto. He intentado lanzar a TintContextWrapper lugar de MyActivity , que funciona bien, pero no puedo averiguar cómo obtener MyActivity de TintContextWrapper .

    Así que mis preguntas son:

    1. ¿Cómo puedo obtener MyActivity de TintContextWrapper ?
    2. ¿Por qué mi ImageButton repente envuelto en un TintContextWrapper .
    3. ¿Debería esperarse realmente este comportamiento?

    Definición de ImageButton en xml es simplemente:

     <ImageButton android:id="@+id/my_id" android:src="@drawable/my_icon" /> 

    Rastro de la pila:

     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) 

  • Ofrecer funciones gratuitas a compradores anteriores
  • La notificación de Android no desaparece después de hacer clic en la notificación
  • La aplicación androide Cordova 5.0.0 no puede conectarse a Internet con Android 4.0.0
  • Cómo conectar múltiples recyclerview o fragmento de animación como se muestra
  • Android Eliminar archivo con DDMS
  • ¿Cómo puedo integrar la pasarela de pago ATOM en mi aplicación?
  • 7 Solutions collect form web for “Librería de soporte de Android 23.4.0: android.support.v7.widget.TintContextWrapper no se puede publicar en Actividad”

    1. Tanto la actividad n TintContextWRapper viene de ContextWrapper . ContextWrapper tiene un método getBaseContext() . Debería ser fácil crear un método de bucle que compruebe la instanceof WrapContext , obtenga el contexto base y, a continuación, compruebe la instanceof Activity . (Si tienes problemas con este método comentario aquí que voy a cavar en algún proyecto mío y pegar aquí a u)

    2. Debido a que AppCompat envuelve su contexto para poder inyectar "compat" vistas y "compat" tintado y otras cosas "compat". Eso es normal.

    3. Sí. Así es como AppCompat hace su cosa.

    Krøllebølle

    Librería de soporte de Android 23.4.0: android.support.v7.widget.TintContextWrapper no se puede publicar en Actividad

    La respuesta a usted pregunta es: primero su código del acontecimiento del tecleo debe ser como:

     @Override public void onClick(View view) { MyActivity myActivity = getRequiredActivity(view); myActivity.showIngredientActivity(mIngredient); } 

    Y luego escribir la función getRequiredActivity ():

     private Activity getRequiredActivity(View req_view) { Context context = req_view.getContext(); while (context instanceof ContextWrapper) { if (context instanceof Activity) { return (Activity)context; } context = ((ContextWrapper)context).getBaseContext(); } return null; 

    }

    Y su Crash / Excepción es fijo 🙂

    Mi sugerencia es pasar una referencia de su actividad en el onClickListener para evitar el problema con TintContextWrapper . Dar a su clase una referencia a MyActivity es simple y evita posibles problemas de casting.

    Puedes probar

     Activity activity = (Activity) view.getRootView().getContext() 

    Obtiene el contexto que contiene esta vista sin el contenedor de android.support.v7.widget.TintContextWrapper.

    1. ¿Cómo puedo obtener MyActivity de TintContextWrapper?

    Realmente no deberías. No hay garantía de que el Contexto de una Vista sea una Actividad – definitivamente no es una Actividad específica. ¿Dónde está configurando su OnClickListener? Estoy asumiendo que en el lugar donde usted establece el oyente, usted tendrá acceso a la actividad. Por ejemplo, si está configurando el listener de una Actividad:

     public class MainActivity extends AppCompatActivity { @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.ingredientButton).setOnClickListener( new IngredientItemOnClickListener(yourIngredient)); } void showIngredientActivity(Ingredient ingredient) { // Do your stuff } public class IngredientItemOnClickListener implements OnClickListener { private Ingredient mIngredient; public IngredientItemOnClickListener(Ingredient ingredient) { mIngredient = ingredient; } @Override public void onClick(View view) { showIngredientActivity(mIngredient); } } } 

    Funcionó para mí después de actualizar las bibliotecas de soporte de Android.

    Me enfrenté al mismo problema y se resolvió con
    – Biblioteca de soporte de Android, revisión 24.2.1 (septiembre de 2016)
    – compileSdkVersion 24
    – buildToolsVersion "24.0.3"

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.