Обновление данных в RecyclerView с помощью RecyclerView.OnScrollListener

120
07 апреля 2021, 00:00

Проблема в том, что при выполнение нового запроса на сервер после прокручивания у меня список полностью обновляется, необходимо, чтобы он добавлялся к прошлому. Я думаю мне нужно как-то в HomePresenter смотреть, если уже есть данных, то добавить новые. Не могу понять как это сделать, только начал изучать и пробывать MVP (Или это проблема в адаптере?)

public class HomeActivity extends AppCompatActivity implements HomeView{

    @BindView(R.id.recyclerView)
    RecyclerView recyclerView;
    HomePresenter presenter;
    private static int offset;
    private static boolean isLoading;
    public static void setIsLoading(boolean isLoading) {
        HomeActivity.isLoading = isLoading;
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        ButterKnife.bind(this);
        presenter = new HomePresenter(this);
        presenter.getData(offset);
        offset = 0;
        isLoading = true;
    }

    @Override
    public void setData(List<PokemonData.Pokemon> pokemons) {
        RecyclerViewHomeAdapter homeAdapter = new RecyclerViewHomeAdapter(pokemons, this);
        recyclerView.setAdapter(homeAdapter);
        GridLayoutManager layoutManager = new GridLayoutManager(this, 2, RecyclerView.VERTICAL, false);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.addOnScrollListener(new RecyclerViewOnScroll() {
            @Override
            protected void loadMore() {
                if (isLoading) {
                    offset+=30;
                    presenter.getData(offset);
                    isLoading = false;
                }
            }
        });
        homeAdapter.notifyDataSetChanged();
    }

HomePresenter:

public class HomePresenter {
    private HomeView view;

    public HomePresenter(HomeView view) {
        this.view = view;
    }
    void getData(int offset) {
        Call<PokemonData> pokemonDataCall = Utils.getApi().getData(offset, 30);
        pokemonDataCall.enqueue(new Callback<PokemonData>() {
            @Override
            public void onResponse(Call<PokemonData> call, Response<PokemonData> response) {
                HomeActivity.setIsLoading(true);
                if (response.isSuccessful() && response.body() != null) {
                    view.setData(response.body().getResults());
                }
                else {
                    view.onErrorLoading(response.message());
                }
            }
            @Override
            public void onFailure(Call<PokemonData> call, Throwable t) {
                HomeActivity.setIsLoading(true);
                view.onErrorLoading(t.getLocalizedMessage());
            }
        });
    }
}
Answer 1

Предлагаю использовать DiffCallback, создаёшь диф класс, в одном методе необходимо прописать поля, по которым старый и новый объект считаются, одним и тем же побъектом, во втором методе, определяешь состояние каких полей может измениться, чтоб этот объект должен был быть изменён в адаптере. Вот статься на медиум https://medium.com/@iammert/using-diffutil-in-android-recyclerview-bdca8e4fbb00 Или погугли примеров довольно много.

Answer 2

Если кому-то поможет решение, необходимо было вынести всю инициализацию из метода setData.

    public class HomeActivity extends AppCompatActivity implements HomeView{

    @BindView(R.id.recyclerView)
    RecyclerView recyclerView;
    @BindView(R.id.btn_refresh)
    FloatingActionButton btn_refresh;
    HomePresenter presenter;
    private List<PokemonData.Pokemon> items = new ArrayList<>();
    private static int offset;
    private static boolean isLoading;
    private RecyclerViewHomeAdapter homeAdapter;
    public static void setIsLoading(boolean isLoading) {
        HomeActivity.isLoading = isLoading;
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        ButterKnife.bind(this);
        presenter = new HomePresenter(this);
        presenter.getData(offset);
        offset = 0;
        isLoading = true;
        homeAdapter = new RecyclerViewHomeAdapter(items, this);
        recyclerView.setAdapter(homeAdapter);
        GridLayoutManager layoutManager = new GridLayoutManager(this, 2, RecyclerView.VERTICAL, false);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.addOnScrollListener(new RecyclerViewOnScroll() {
            @Override
            protected void loadMore() {
                if (isLoading) {
                    offset+=30;
                    presenter.getData(offset);
                    isLoading = false;
                    homeAdapter.setPokemonList(items);
                }
            }
        });
    }
    @Override
    public void setData(List<PokemonData.Pokemon> pokemons) {
        items.addAll(pokemons);
        homeAdapter.setPokemonList(items)
    }
}
READ ALSO
Как именно работает метод read() у InputStream?

Как именно работает метод read() у InputStream?

Как же все-таки устроена работа метода read():

117
Подскажите как реализовать сервер для Android приложений

Подскажите как реализовать сервер для Android приложений

Я разрабатываю приложение под Android и хотел бы узнать как реализовать сервер который бы принимал данные и сохранял их в базу данных желательно...

115
Запись матрицы в csv файл на java

Запись матрицы в csv файл на java

Основное задание заключается в том, что б поменять местами столбики в csv файлеЯ выгрузила их оттуда в матрицу, написала цикл с заменой столбиков,...

117
Чем отличаются методы от конструкторов в java?

Чем отличаются методы от конструкторов в java?

Чем отличаются методы от конструкторов в java? Для чего нужно то и другое?

94