Transformations.distinctUntilChanged() not working with equals() override

474 Views Asked by At

My Aim: I would like to use the Transformations.distinctUntilChanged() method to create an application which shows a toast message every time a LiveData object is updated. The LiveData object is a simple custom Integer object (MyInteger) that increments by one every time a button is clicked. The application should stop showing the toast message when myInteger exceeds 5. To implement this >5 condition, the application must override the equals() method of MyInteger class (the equals() method is called in the distinctUntilChanged() class).

The Problem: In the below code, the currentValue and previousValue fields are always the same (except for first time button is clicked). Hence onChanged is not called in MainActivity and the Toast message does not show from the second click onwards. See below for current result vs. what i expect should happen.

Please help. Again the application must use distinctUntilChanged() and overridden equals() methods together.

Current result:
First time button clicked: currentValue=1 and previousValue=null, Toast Message shows.
Second time button clicked: currentValue=2 and previousValue=2, Toast Message does not show.
Third time button clicked: currentValue=3 and previousValue=3, Toast Message does not show.
Fourth time button clicked: currentValue=4 and previousValue=4, Toast Message does not show.
and so on...

Desired result:
First time button clicked: currentValue=1 and previousValue=null, Toast Message shows.
Second time button clicked: currentValue=2 and previousValue=1, Toast Message shows.
Third time button clicked: currentValue=3 and previousValue=2, Toast Message shows.
Fourth time button clicked: currentValue=4 and previousValue=3, Toast Message shows.
and so on...

Blockquote

public class MainActivity extends AppCompatActivity {

    private MainActivityViewModel mMainActivityViewModel;
    Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = findViewById(R.id.my_button);
        MyInteger myInteger = new MyInteger(0);
        mMainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                myInteger.incrementByOne();
                mMainActivityViewModel.getLiveData().setValue(myInteger);
            }
        });

        Transformations.distinctUntilChanged(mMainActivityViewModel.getLiveData()).observe(this, new Observer<MyInteger>() {
            @Override
            public void onChanged(MyInteger myInteger) {
                Log.wtf("Transformations onChanged:", String.valueOf(myInteger.integer));
                Toast.makeText(MainActivity.this, "Transformations onChanged:"+String.valueOf(myInteger.integer), Toast.LENGTH_SHORT).show();
            }
        });
    }
}

Blockquote

public class MainActivityViewModel extends AndroidViewModel {

    public MutableLiveData<MyInteger> myIntegerMutableLiveData;

    public MainActivityViewModel(@NonNull Application application) {
        super(application);
    }

    public MutableLiveData<MyInteger> getLiveData() {

        if (myIntegerMutableLiveData == null) {
            myIntegerMutableLiveData = new MutableLiveData<>();
        }

//        MediatorLiveData transformedLiveData = (MediatorLiveData) Transformations.distinctUntilChanged(myIntegerMutableLiveData);

        return myIntegerMutableLiveData;
    }

}

Blockquote

public class MyInteger {
    
    public int integer;
    
    public MyInteger(Integer integer) {
        this.integer = integer;
    }

    public void incrementByOne() {
        integer++;
    }

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    MyInteger myInteger = (MyInteger) o;
    if ((myInteger.integer <= 5) && (integer == myInteger.integer)) {return true;}
    if ((myInteger.integer <= 5) && (integer != myInteger.integer)) {return false;}
    return (myInteger.integer > 5);
}

    @Override
    public int hashCode() {
        return Objects.hash(integer);
    }
}
0

There are 0 best solutions below