简体   繁体   中英

LiveData fails to notify it's observer of changes in PagedList object

I have written this simple example to test paging library and observe changes to PagedList using LiveData but it notifies the observer only once, when the LiveData<PagedList<Integer>> object is created. I load more data using a button in my activity and pagedList object is loaded correctly but changes are not observed. here's the code for my activity:

import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.arch.paging.PagedList;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final MainViewModel mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);

        Button b = findViewById(R.id.button);
        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PagedList<Integer> s = mainViewModel.getIntegers().getValue();
                s.loadAround(s.size());
            }
        });
        mainViewModel.setUpPaging(1);
        mainViewModel.getIntegers().observe(this, new Observer<PagedList<Integer>>() {
            @Override
            public void onChanged(@Nullable PagedList<Integer> integers) {
                //logging some text
                Log.i("MyLog","new list Observed");

            }
        });


    }
}

here's my ViewModel class:

import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.ViewModel;
import android.arch.paging.LivePagedListBuilder;
import android.arch.paging.PagedList;

public class MainViewModel extends ViewModel {

    LiveData<PagedList<Integer>> integers;

    public LiveData<PagedList<Integer>> getIntegers() {
        return integers;
    }
    public void setUpPaging(Integer startFrom){

        integers = new LivePagedListBuilder<Integer,Integer>(IntegersDataSource.randomNumbersStartingFrom(startFrom),
                new PagedList.Config.Builder()
                        .setPageSize(5)
                .setEnablePlaceholders(false)
                .build()).build();
    }

}

and here's my DataSource which for simplicity only generate random integers :

import android.arch.paging.DataSource;
import android.arch.paging.PageKeyedDataSource;
import android.support.annotation.NonNull;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class IntegersDataSource extends PageKeyedDataSource<Integer,Integer> {
    private Integer initialInt;
    private final Integer BOUND = 300;

    public IntegersDataSource(Integer initialInt) {
        this.initialInt = initialInt;
    }

    @Override
    public void loadInitial(@NonNull LoadInitialParams<Integer> params, @NonNull LoadInitialCallback<Integer, Integer> callback) {
        Random r = new Random();
        Integer i = r.nextInt(BOUND - 1) + 1;
        List<Integer> l = new ArrayList<>();
        l.add(i);
        callback.onResult(l,initialInt-1, initialInt+1);

    }

    @Override
    public void loadBefore(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, Integer> callback) {

        Random r = new Random();
        Integer i = r.nextInt(BOUND - 1) + 1;
        List<Integer> l = new ArrayList<>();
        l.add(i);
        callback.onResult(l, params.key-1);

    }

    @Override
    public void loadAfter(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, Integer> callback) {
        Random r = new Random();
        Integer i = r.nextInt(BOUND - 1) + 1;
        List<Integer> l = new ArrayList<>();
        l.add(i);
        callback.onResult(l, params.key+1);
    }
    private static class RandomsFactory extends DataSource.Factory{
        Integer srartFrom;
        public RandomsFactory(Integer startFrom) {
            this.srartFrom = startFrom;
        }

        @Override
        public DataSource create() {
            return new IntegersDataSource(srartFrom);
        }
    }

        public static DataSource.Factory<Integer, Integer> randomNumbersStartingFrom(Integer startFrom) {
        return new RandomsFactory(startFrom);
    }
}

and this is in my build gradle :

implementation "android.arch.paging:runtime:1.0.0-rc1"

I keep pushing the button multiple times but only one time it is observed(for creation time).

PagedListAdapter doesn't reflect changed item itself. To put it another way, PagedList is immutable. you should call invalidate() on the current DataSource when an update occurs. A new PagedList / DataSource pair will be created via LivePagedListBuilder and It will be passed through LiveData to observers when the current DataSource is invalidated.

Try this code.

b.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        PagedList<Integer> s = mainViewModel.getIntegers().getValue();
        s.getDataSource().invalidate();    
    }
});

Please check out this demo app.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM