Android双向数据绑定:Float与EditText绑定失败编译报错求助
Let's break down why you're hitting that NullPointerException and fix it step by step:
Root Cause
Your Product class uses nullable Float? properties, but your Converter methods expect non-null float primitives. When product.width is null, passing it to floatToString(float) causes an unboxing NPE during data binding code generation. Additionally, your Product properties are declared as immutable val and don't implement the required observable callbacks for two-way binding to work properly.
Step 1: Update the Converter to Handle Nullable Floats
Modify your Converter class to accept and return nullable types, so it can safely handle null values from your Product class:
public class Converter { @InverseMethod("stringToNullableFloat") public static String nullableFloatToString(Float value) { if (value == null) { return ""; } try { return String.valueOf(value); } catch (Exception e) { return ""; } } public static Float stringToNullableFloat(String value) { if (value == null || value.trim().isEmpty()) { return null; } try { return Float.parseFloat(value.trim()); } catch (NumberFormatException e) { return null; } } }
Step 2: Fix the Product Class for Observable Two-Way Binding
Since you're extending BaseObservable, you need to make your properties mutable (var), add @get:Bindable annotations, and notify property changes in the setters. Immutable val properties can't support two-way binding because the value can't be updated:
import android.databinding.BaseObservable import android.databinding.Bindable import com.yourpackage.BR // Use your auto-generated BR class data class Product( private var _height: Float?, private var _length: Float?, private var _width: Float?, private var _weight: Float? ) : BaseObservable() { @get:Bindable var height: Float? get() = _height set(value) { _height = value notifyPropertyChanged(BR.height) } @get:Bindable var length: Float? get() = _length set(value) { _length = value notifyPropertyChanged(BR.length) } @get:Bindable var width: Float? get() = _width set(value) { _width = value notifyPropertyChanged(BR.width) } @get:Bindable var weight: Float? get() = _weight set(value) { _weight = value notifyPropertyChanged(BR.weight) } }
Step 3: Adjust the Layout Binding
Update your XML to use the new converter method, and fix the inputType to support decimal values (critical for Float types):
<com.google.android.material.textfield.TextInputLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="16dp"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/width" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Width" android:inputType="numberDecimal" <!-- Updated to support decimal inputs --> android:text="@={Converter.nullableFloatToString(product.width)}"/> </com.google.android.material.textfield.TextInputLayout>
Quick Check
Ensure data binding is enabled in your app-level build.gradle file:
android { ... buildFeatures { dataBinding true } }
内容的提问来源于stack exchange,提问作者Danny Spijker

