studio llenar example dinamico custom android android-listview android-switch

llenar - listview material design android



Cambiar el estado del interruptor sin animaciĆ³n (6)

Al llamar a jumpDrawablesToCurrentState() se omitirá la animación.

En mi proyecto de Android, tengo un ListView con filas que contienen elementos SwitchCompat (widget de AppCompat for Switch ).

Mi problema ocurre cuando me getView(...) a la lista y el getView(...) de MyAdapter se invoca con una vista recycled . Redefino el estado correcto de Switch pero la animación es visible.

¿Hay una solución para evitar la animación en este caso?


El problema con la reproducción de animaciones en la lista puede estar presente si usa el Enlace de datos de Android.

Para resolverlo, ejecute el método binding.executePendingBindings() después de configurar los datos: actualizará el estado de enlace del componente en el marco actual y no esperará a que llegue el siguiente.

Como ya habrás adivinado, el siguiente fotograma es la animación.


Finalmente encontré una solución pero no parece realmente limpia:

ViewGroup viewGroup = (ViewGroup) view; // the recycled view viewGroup.removeView(switch); switch.setChecked(states[index]); viewGroup.addView(switch);

Si existe una solución mejor, por favor compártelo.


Para el desarrollador de Kotlin:

fun SwitchCompat.setCheckedWithoutAnimation(checked: Boolean) { val beforeVisibility = visibility visibility = View.INVISIBLE isChecked = checked visibility = beforeVisibility }

Y el uso:

mySwitch.setCheckedWithoutAnimation(true)


Tuve el mismo problema y logré resolverlo con una reflexión mínima.

Uso:

Para cambiar el estado del conmutador sin animación, llame al setChecked(boolean checked, boolean animate) con falso para el parámetro animado. Si el interruptor ya está animando en el momento en que se llama a este método, la animación se detendrá y el interruptor saltará a la posición deseada.

SwitchCompatFix.java

import android.content.Context; import android.support.v7.widget.SwitchCompat; import android.util.AttributeSet; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * Work around for: http://.com/questions/27139262/change-switch-state-without-animation * Possible fix for bug 101107: https://code.google.com/p/android/issues/detail?id=101107 * * Version 0.2 * @author Rolf Smit */ public class SwitchCompatFix extends SwitchCompat { public SwitchCompatFix(Context context) { super(context); initHack(); } public SwitchCompatFix(Context context, AttributeSet attrs) { super(context, attrs); initHack(); } public SwitchCompatFix(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initHack(); } private Method methodCancelPositionAnimator = null; private Method methodSetThumbPosition = null; private void initHack(){ try { methodCancelPositionAnimator = SwitchCompat.class.getDeclaredMethod("cancelPositionAnimator"); methodSetThumbPosition = SwitchCompat.class.getDeclaredMethod("setThumbPosition", float.class); methodCancelPositionAnimator.setAccessible(true); methodSetThumbPosition.setAccessible(true); } catch (NoSuchMethodException e) { e.printStackTrace(); } } public void setChecked(boolean checked, boolean animate){ // Java does not support super.super.xxx calls, a call to the SwitchCompat default setChecked method is needed. super.setChecked(checked); if(!animate) { // See original SwitchCompat source: // Calling the super method may result in setChecked() getting called // recursively with a different value, so load the REAL value... checked = isChecked(); // Cancel any running animations (started by super.setChecked()) and immediately move the thumb to the new position try { if(methodCancelPositionAnimator != null && methodSetThumbPosition != null) { methodCancelPositionAnimator.invoke(this); methodSetThumbPosition.invoke(this, checked ? 1 : 0); } } catch (IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } } }

Nota para los usuarios de proguard:

Debido a que este método utiliza la reflexión, podría ser necesaria una regla de progreso adicional (si aún no está presente).

-keep class android.support.v7.widget.SwitchCompat { private void cancelPositionAnimator(); private void setThumbPosition(float); }

Esta regla adicional no es necesaria cuando utiliza una de las siguientes reglas de programación (o similares):

-keep class android.support.v7.widget.** { *; } -keep class android.support.v7.** { *; }


Utilizando SwitchCompat y DataBinding

@BindingAdapter({"bind:checkedState"}) public static void setCheckedState(SwitchCompat switchView, boolean checked) { int visibility = switchView.getVisibility(); switchView.setVisibility(View.INVISIBLE); switchView.setChecked(checked); switchView.setVisibility(visibility); }

Luego en xml:

<android.support.v7.widget.SwitchCompat android:id="@+id/my_switch" android:layout_width="wrap_content" android:layout_height="wrap_content" app:checkedState="@{my_data.checked}"/>

Y no olvide llamar a executePendingBindings() (gracias AAverin )