luckysing_noobster
luckysing_noobster

Reputation: 2003

Two way binding cannot resolve a setter

I am trying to learn about data binding I have my CreditCardViewModel class which is bind in my fragment as follows

public class CreditCardValidatorFragment extends Fragment {

    private CreditCardViewModel cardViewModel;
    private CcValidateFragmentBinding binding;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        binding = DataBindingUtil.inflate(inflater, R.layout.cc_validate_fragment, container, false);
        return binding.getRoot();
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        cardViewModel = ViewModelProviders.of(this).get(CreditCardViewModel.class);
        binding.setCreditCardViewModel(cardViewModel);
        binding.submitButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Navigation.findNavController(view).navigate(CreditCardValidatorFragmentDirections.actionMainFragmentToSecondFragment("Arvinder"));
            }
        });
        //required to update UI with Live data
        binding.setLifecycleOwner(this);

    }

}
public class CreditCardViewModel extends ViewModel {
    private MutableLiveData<String> firstName = new MutableLiveData<>();
    private MutableLiveData<String> lastName = new MutableLiveData<>();
    private MutableLiveData<Long> ccNumber = new MutableLiveData<>();
    private MutableLiveData<Integer> ccType = new MutableLiveData<>();
    private MutableLiveData<String> exp = new MutableLiveData<>();
    private MutableLiveData<Integer> cvv = new MutableLiveData<>();

    public String getFirstName() {
        return firstName.getValue();
    }

    public String getLastName() {
        return lastName.getValue();
    }

    public Long getCcNumber() {
        return ccNumber.getValue().longValue();
    }

    public Integer getCcType() {
        return ccType.getValue();
    }

    public String getExp() {
        return exp.getValue();
    }

    public Integer getCvv() {
        return cvv.getValue();
    }

    public void onCvvTextChanged(CharSequence text) {
        cvv.setValue(Integer.valueOf(text.toString()));
    }

    public void onFirstNameChanged(CharSequence text) {
        firstName.setValue(text.toString());
    }

    public void onLastNameChanged(CharSequence text) {
        lastName.setValue(text.toString());
    }

    public void onCCNumberChanged(CharSequence text) {
        ccNumber.setValue(Long.valueOf(text.toString()));
    }

    public void onExpChanged(CharSequence text) {
        exp.setValue(text.toString());
    }

    public void onCCTypeChanged(CharSequence text) {
        ccType.setValue(Integer.valueOf(text.toString()));
    }
}

Part of my layout

<EditText
            android:id="@+id/cvvEdit"
            android:layout_width="wrap_content"
            android:layout_height="48dp"
            android:layout_marginStart="36dp"
            android:layout_marginLeft="36dp"
            android:layout_marginTop="24dp"
            android:afterTextChanged="@{(text) -> creditCardViewModel.onCvvTextChanged(text)}"
            android:ems="10"
            android:inputType="number"
            android:text="@={creditCardViewModel.cvv}"
            app:layout_constraintStart_toEndOf="@+id/cvv"
            app:layout_constraintTop_toBottomOf="@+id/expirationEdit" />

I received the following error when trying to set the cvv in my layout :

      android:text="@={creditCardViewModel.cvv}"

The expression 'creditCardViewModel.getCvv()' cannot be inverted, so it cannot be used in a two-way binding

Details: Two-way binding cannot resolve a setter for java.lang.Integer property 'cvv'

I tried to add getters and setters in the viewModel to get property correctly but still get the error .

Upvotes: 2

Views: 2490

Answers (1)

Akshay Raiyani
Akshay Raiyani

Reputation: 1323

Make it your private variable to the public in your ViewModel

public MutableLiveData<String> firstName = new MutableLiveData<>();
public MutableLiveData<String> lastName = new MutableLiveData<>();
public MutableLiveData<Long> ccNumber = new MutableLiveData<>();
public MutableLiveData<Integer> ccType = new MutableLiveData<>();
public MutableLiveData<String> exp = new MutableLiveData<>();
public MutableLiveData<Integer> cvv = new MutableLiveData<>();

And you have to convert your integer to string

android:text="@={String.valueOf(creditCardViewModel.cvv)}"

Upvotes: 2

Related Questions