android - studio - enlace de datos-advertencia de SafeUnbox
data binding vs butterknife (7)
después de actualizar la versión AS Gradle a 2.3.0, el enlace de datos encuentra una advertencia:
Advertencia: selectMap [índice] es un campo en el recuadro, pero debe desmarcarse para ejecutar selectMap [índice]? @android: color / blanco: @android: color / transparente. Esto puede causar NPE, por lo que el enlace de datos lo desempaquetará. Puede cambiar la expresión y envolver explícitamente selectMap [index] con safeUnbox () para evitar la advertencia
selectMap es un ObservableMap, luego busco esta advertencia, pero solo tuve algunas discusiones y no la solucioné
Android Studio 2.3.0-alpha1: Databinding + int unboxing provoca errores de compilación
Enlace de datos: el objeto de datos es nulo en la API 15-18
Sigo el camino en los enlaces, selectMap[index]
a safeUnbox(selectMap[index])
pero tengo un error de sintaxis.
¿Alguien sabe como arreglar esta advertencia?
Edición: Aquí está el código del archivo xml
<?xml version="1.0" encoding="utf-8"?>
<data class="SupportCountryViewHolderBinding">
<variable
name="viewModel"
type="com.goodarc.care_about.activity.account.support_country.SupportCountryHolderViewModel" />
<variable
name="dataSource"
type="com.goodarc.care_about.module.assets_file.SupportCountry" />
<variable
name="selectMap"
type="android.databinding.ObservableMap<Integer, Boolean>" />
<variable
name="index"
type="int" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@{selectMap[index] ? @android:color/white : @android:color/transparent}"
android:onClick="@{(v) -> viewModel.onItemSelectListener(selectMap, index)}"
android:orientation="vertical"
android:padding="20dp">
<TextView
style="@style/TitleLabel2"
android:layout_gravity="center_vertical|start"
android:text="@{dataSource.display}"
android:textColor="@{selectMap[index] ? @android:color/black : @android:color/white}"
tools:text="Taiwan (+886)" />
</LinearLayout>
La construcción es exitosa, pero la advertencia sale (paso más arriba).
Estoy hablando de Boolean, esta solución es igual para Integer
, Double
, Character
, etc.
w: advertencia: habilitado es un campo en el recuadro pero debe desmarcarse para ejecutar Android: marcado .
Esta advertencia llega porque el campo habilitado puede ser nulo. Si toma Boolean
lugar de Boolean
, Boolean
puede ser nulo. Así que viene esta advertencia. Que este campo puede hacer NullPointerException
.
---------------- Caso 1 - Encuadernación unidireccional ----------------
@Bindable
public boolean getAvoidXpressway() {
return commute.getAvoidXpressway();
}
public void setAvoidXpressway(Boolean avoidXpressway) {
commute.setAvoidXpressway(avoidXpressway);
notifyPropertyChanged(BR.avoidXpressway);
}
Solución 1
android:alpha="@{alpha != null ? safeUnbox(alpha) : 0.5f}"
Solucion 2
Cambiar Boolean
a tipo primitivo boolean
. Para que nunca sea nulo, el valor predeterminado de boolean
es false
.
android:visibility="@{viewmodel.isLoading ? View.INVISIBLE : View.VISIBLE}"
---------------- Caso 2 - Enlace bidireccional ----------------
Cuando tiene un enlace bidireccional, entonces no puede usar el modo safeUnbox()
, porque safeUnbox()
no se invertirá .
android:visibility="@{safeUnbox(viewmodel.isLoading) ? View.INVISIBLE : View.VISIBLE}"
Esto no funcionará ahora.
<variable
name="enabled"
type="Boolean"/>
....
<Switch
android:checked="@{enabled}"
/>
Solución 1
Cambiar Boolean
a tipo primitivo boolean
. Para que nunca sea nulo, el valor predeterminado de boolean
es falso.
<Switch
android:checked="@{safeUnbox(fieldName)}"
/>
Solucion 2
Un largo camino es hacer adaptadores de enlace inverso para safeUnbox . Ver aqui
¿Qué es el método safeUnbox ()?
safeUnbox()
simplemente safeUnbox()
valor nulo y devuelve el valor no nulo. A continuación puede ver los métodos que se definen en la biblioteca de enlace de datos.
<variable
name="enabled"
type="boolean"/>
Agregar el safeUnbox()
a la variable de advertencia hará que esta advertencia desaparezca y seguirá funcionando bien
<Switch
android:checked="@{safeUnbox(fieldName)}"
/>
En lugar de ObservableField<T>
, debe usar una versión especial para los primitivos:
-
ObservableInt
para elint
-
ObservableBoolean
para elboolean
-
ObservableFloat
para elfloat
-
ObservableChar
para elchar
-
ObservableLong
para ellong
-
ObservableByte
para elbyte
-
ObservableShort
para elshort
En una BaseObservable
esto también puede suceder. Necesitaba actualizar el tipo de booleano a booleano.
<variable
name="enabled"
type="Boolean"/>
....
<Switch
android:checked="@={enabled}"
/>
Si está enlazando utilizando un objeto externo como en mi caso, asegúrese de que el tipo return también sea booleano; De lo contrario, la advertencia seguirá apareciendo.
Puedes agregar safeUnbox de esta manera:
android:text="@{Double.toString(safeUnbox(product.listPrice))}"
Tuve esta advertencia emergente cuando hice algo como:
<variable
name="enabled"
type="boolean"/>
añadiendo safeunbox así:
public static int safeUnbox(java.lang.Integer boxed) {
return boxed == null ? 0 : (int)boxed;
}
public static long safeUnbox(java.lang.Long boxed) {
return boxed == null ? 0L : (long)boxed;
}
public static short safeUnbox(java.lang.Short boxed) {
return boxed == null ? 0 : (short)boxed;
}
public static byte safeUnbox(java.lang.Byte boxed) {
return boxed == null ? 0 : (byte)boxed;
}
public static char safeUnbox(java.lang.Character boxed) {
return boxed == null ? ''/u0000'' : (char)boxed;
}
public static double safeUnbox(java.lang.Double boxed) {
return boxed == null ? 0.0 : (double)boxed;
}
public static float safeUnbox(java.lang.Float boxed) {
return boxed == null ? 0f : (float)boxed;
}
public static boolean safeUnbox(java.lang.Boolean boxed) {
return boxed == null ? false : (boolean)boxed;
}
eliminado la advertencia después de la reconstrucción
Tuve la misma advertencia, en mi caso, al cambiar la declaración de variable de tipo booleano a tipo booleano se solucionó el problema:
De:
<variable
name="readOnly"
type="Boolean" />
A:
<variable
name="readOnly"
type="boolean" />
Entonces, tal vez puedas probar con:
<variable
name="selectMap"
type="android.databinding.ObservableMap<Integer, boolean>" />