Obtener una clase vinculante desde vista
Tengo una clase de CustomView con una disposición del databound que toma una variable. En el diseño que contiene el CustomView, quiero pasar un atributo en el CustomView y hacer que CustomView pase ese atributo en el enlace de su propio diseño. Esto es lo que tengo:
public class CustomView extends LinearLayout { public CustomView(Context inContext, AttributeSet inAttrs) { super(inContext, inAttrs); inflate(inContext, R.layout.custom_view, null); } @BindingAdapter({"app:variable"}) public static void SetVariable(CustomView inCustomView, VariableType inMyVariable) { CustomViewBinding binding = DataBindingUtil.getBinding(inCustomView); binding.setMyVariable(inMyVariable); } }
Esto se bloquea tratando de extraer el enlace de la vista. ¿Es esto posible? Aquí está el rastreo de la pila:
- Enlace de datos de Android layout_width y layout_height
- La vinculación de datos de Android hace que la aplicación se bloquee cuando se utiliza una etiqueta de inclusión en un grupo de usuarios no root
- Android Spinner databind usando la lista de matrices
- Android dataBinding - cómo utilizar el recurso bool para activar la visibilidad del diseño
- Formato HTML en la nueva biblioteca de enlace de datos de Android
java.lang.NullPointerException: Attempt to invoke virtual method 'void xxx.databinding.CustomViewBinding.setVariableType(xxx.VariableType)' on a null object reference at xxx.CustomView.SetDynamicList(CustomView.java:32) at xxx.MyFragmentBinding.executeBindings(MyFragmentBinding.java:116) at android.databinding.ViewDataBinding.executePendingBindings(ViewDataBinding.java:350) at android.databinding.ViewDataBinding$6.run(ViewDataBinding.java:167) at android.databinding.ViewDataBinding$7.doFrame(ViewDataBinding.java:233) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:856) at android.view.Choreographer.doCallbacks(Choreographer.java:670) at android.view.Choreographer.doFrame(Choreographer.java:603) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Y si cambio
DataBindingUtil.getBinding(inCustomView)
a
DataBindingUtil.bind(inCustomView)
Entonces tengo esto:
java.lang.IllegalArgumentException: View is not a binding layout at android.databinding.DataBindingUtil.bind(DataBindingUtil.java:166) at android.databinding.DataBindingUtil.bind(DataBindingUtil.java:140) at xxx.CustomView.SetDynamicList(CustomView.java:30) - at xxx.databinding.MyFragmentBinding.executeBindings(MyFragmentBinding.java:116) at android.databinding.ViewDataBinding.executePendingBindings(ViewDataBinding.java:350) at android.databinding.ViewDataBinding$6.run(ViewDataBinding.java:167) at android.databinding.ViewDataBinding$7.doFrame(ViewDataBinding.java:233) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:856) at android.view.Choreographer.doCallbacks(Choreographer.java:670) at android.view.Choreographer.doFrame(Choreographer.java:603) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Esto podría implicar que el archivo de diseño no está formateado para enlace de datos, pero lo es. Tiene el elemento de diseño, y el elemento de datos con variables y todo.
- Vinculación de datos de Android - Referencia para ver
- Android - DataBinding - ¿Cómo y cuándo se generarán las clases de enlace?
- DataBinding con Android Dialog
- Android Data Binding: no puede encontrar el setter para el atributo
- Problema con enlace de datos usando Kotlin para Android
- Android databinding - Cómo obtener dimensiones desde dimens.xml
- Cómo pasar ObservableField dentro del control interno
- Conexión de datos de Android con menús
Debe vincular la vista inflada para crear el enlace de datos. En su ejemplo, está vinculando el contenedor del diseño.
Usted puede hacer esto de varias maneras. Lo más fácil es vincularlo como parte de la inflación:
public class CustomView extends LinearLayout { CustomViewBinding mBinding; public CustomView(Context inContext, AttributeSet inAttrs) { super(inContext, inAttrs); LayoutInflater inflater = LayoutInflater.from(inContext); // I assume you want it inflated into this ViewGroup mBinding = CustomViewBinding.inflate(inflater, this, true); } public void setVariable(CustomView inCustomView, VariableType inMyVariable) { mBinding.setVariable(inMyVariable); } ... }
Realmente no necesita un adaptador de enlace a menos que no desee que el setter forme parte de su vista personalizada. En ese caso, todavía necesitará una forma de obtener el enlace, por lo que tendrá que agregar algo como esto:
public CustomViewBinding getBinding() { return mBinding; }
Para que su adaptador de enlace funcione.
Si sabe que los contenidos de LinearLayout van a ser desde la vista inflada, puede utilizar un adaptador de enlace como este:
@BindingAdapter({"app:variable"}) public static void setVariable(CustomView inCustomView, VariableType inMyVariable) { if (inCustomView.getChildCount() == 0) { return; } View boundView = inCustomView.getChildAt(0); CustomViewBinding binding = DataBindingUtil.getBinding(boundView); binding.setMyVariable(inMyVariable); }
Si su vista personalizada no es muy personalizada, simplemente puede incluir su diseño directamente:
<include layout="@layout/custom_view" app:variable="@{myVariableValue}"/>
Tendrías, por supuesto, que mover el LinearLayout a custom_view.xml.
- Flotar vistas para que no ocupen espacio en el diseño
- ¿Puedo deshabilitar el desplazamiento en TextView cuando se utiliza LinkMovementMethod?