Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package cz.grejtCZ.ukolnicek.android.headeredList;
- import android.arch.lifecycle.LiveData;
- import android.arch.paging.DataSource;
- import android.arch.paging.PositionalDataSource;
- import android.support.annotation.NonNull;
- import org.joda.time.LocalDate;
- import java.util.LinkedList;
- import java.util.List;
- import cz.grejtCZ.ukolnicek.android.sql.DMO;
- import cz.grejtCZ.ukolnicek.android.sql.SQLUkol;
- /**
- * Hází mezi úkoly hlavičky s datem. úkoly musí být seřazeny podle data.
- * Adds Headers between Ukols. Ukols have to be sorted by date.
- */
- public class MyDatasource extends PositionalDataSource<UkolOrHeader> {
- private final PositionalDataSource<SQLUkol> original;
- private long listID;
- private List<DateCount> dateCounts;
- private int totalHeaders;
- public MyDatasource(PositionalDataSource<SQLUkol> original, long listID) {
- this.original = original;
- this.listID = listID;
- }
- //<editor-fold name="Invalidating">
- @Override
- public void addInvalidatedCallback(@NonNull InvalidatedCallback onInvalidatedCallback) {
- original.addInvalidatedCallback(onInvalidatedCallback);
- }
- @Override
- public void removeInvalidatedCallback(@NonNull InvalidatedCallback onInvalidatedCallback) {
- original.removeInvalidatedCallback(onInvalidatedCallback);
- }
- @Override
- public void invalidate() {
- original.invalidate();
- }
- @Override
- public boolean isInvalid() {
- return original.isInvalid();
- }
- //</editor-fold>
- public static class Factory extends DataSource.Factory<Integer, UkolOrHeader> {
- private DataSource.Factory orig;
- private long listID;
- public Factory(DataSource.Factory<Integer, SQLUkol> orig, long listID) {
- this.orig = orig;
- this.listID = listID;
- }
- @Override
- public DataSource<Integer, UkolOrHeader> create() {
- return new MyDatasource((PositionalDataSource<SQLUkol>) orig.create(), listID);
- }
- }
- /**
- * dostane seznam ukolu a prida mezi nej hlavicky. takze musi dostat seznam s predchozim ukolem nez je prvni zadany
- * gets list of Ukols and adds headers in between, so it needs to receive the Ukol before requested as well.
- */
- private static LinkedList<UkolOrHeader> addHeaders(List<SQLUkol> list, boolean moved) {
- if (list.size() == 0) {
- return new LinkedList<>();
- }
- LinkedList<UkolOrHeader> vrat = new LinkedList<>();
- LocalDate predchozi = null;
- for (int i = 0; i < list.size(); i++) {
- SQLUkol item = list.get(i);
- LocalDate date = item.getDate();
- if(i == 0){
- if (!moved){
- vrat.add(new Header(date));
- }
- }else {
- if (date != null && (predchozi == null || date.isAfter(predchozi))){
- vrat.add(new Header(date));
- }
- }
- vrat.add(new UkolInList(item));
- predchozi = date;
- }
- return vrat;
- }
- //<editor-fold name="Mutable>
- private static class Mutable<T> {
- public T value;
- public Mutable() {
- }
- public Mutable(T value) {
- this.value = value;
- }
- }
- //</editor-fold>
- /**
- * vrati index v databazi, bez headeru
- * EN: Calculate offset
- * returns index of Ukol in database (without headers) corresponding to the given one (from displayed list, with headers)
- * @param naPrelomu is set to true if start is pointing to Header, so you do not have to romove one Ukol later (see =1=)
- */
- private int zapocitejPosun(int start, Mutable<Boolean> naPrelomu/*EN: onEdge*/) {
- int i = 0;
- int pocet = 0;
- while (pocet < start && i < dateCounts.size()) {
- pocet += 1 + dateCounts.get(i).count;
- i++;
- if (pocet == start){
- naPrelomu.value = true;
- }
- }
- return start - i;
- }
- /**
- * vrati index v seznamu odpovidajici ukolu na danem indexy v seznamu v databazni
- * EN: calculate back offset
- * gets index of Ukol in Database (no headers) and returns idex in displeyed list (headers)
- *
- * @param start index ukolu v databazi
- * @return index v headrovanem seznamu
- */
- private int posunZpet(int start) {
- int hederu = 0;
- int i = -1;
- while (i < start) {
- i += dateCounts.get(hederu).count;
- hederu++;
- }
- return start + hederu;
- }
- @Override
- public void loadInitial(@NonNull LoadInitialParams params, @NonNull final LoadInitialCallback callback) {
- int requestedStartPosition = params.requestedStartPosition;
- int requestedLoadSize = params.requestedLoadSize;
- final int originalLoadSize = requestedLoadSize;
- int pageSize = params.pageSize;
- boolean placeholdersEnabled = params.placeholdersEnabled;
- boolean moved = false;
- //shifts loaded area, so that we know if there is a header on the start of requested area
- if (requestedStartPosition != 0) {
- requestedStartPosition--;
- requestedLoadSize++;
- pageSize++;
- moved = true;
- }
- dateCounts = DMO.getDao().getDateCount(listID);
- totalHeaders = dateCounts.size();
- final Mutable<Boolean> naPrelomu = new Mutable<>(false);
- requestedStartPosition = zapocitejPosun(requestedStartPosition,naPrelomu);
- LoadInitialParams newParams = new LoadInitialParams(requestedStartPosition, requestedLoadSize, pageSize, placeholdersEnabled);
- final boolean finalMoved = moved;
- original.loadInitial(newParams, new LoadInitialCallback<SQLUkol>() {
- @Override
- public void onResult(@NonNull List<SQLUkol> data, int position, int totalCount) {
- LinkedList<UkolOrHeader> newList = addHeaders(data, finalMoved);
- int newPosition = posunZpet(position);
- if (finalMoved && !naPrelomu.value) { // =1=
- newList.removeFirst();
- }
- if (newList.get(0) instanceof Header){
- newPosition -= 1;
- }
- int loadSize = originalLoadSize;
- if (loadSize > newList.size()) {
- loadSize = newList.size();
- }
- int total = totalCount + totalHeaders;
- callback.onResult(newList.subList(0, loadSize),newPosition, total);
- }
- @Override
- public void onResult(@NonNull List<SQLUkol> data, int position) {
- LinkedList<UkolOrHeader> newList = addHeaders(data, finalMoved);
- int newPosition = posunZpet(position);
- if (finalMoved && !naPrelomu.value) { // =1=
- newList.removeFirst();
- }
- if (newList.get(0) instanceof Header){
- newPosition -= 1;
- }
- int loadSize = originalLoadSize;
- if (loadSize > newList.size()) {
- loadSize = newList.size();
- }
- callback.onResult(newList.subList(0, loadSize),newPosition);
- }
- });
- }
- @Override
- public void loadRange(@NonNull LoadRangeParams params, @NonNull final LoadRangeCallback callback) {
- int requestedStartPosition = params.startPosition;
- int requestedLoadSize = params.loadSize;
- final int originalLoadSize = requestedLoadSize;
- boolean moved = false;
- //shifts loaded area, so that we know if there is a header on the start of requested area
- if (requestedStartPosition != 0) {
- requestedStartPosition--;
- requestedLoadSize++;
- moved = true;
- }
- final Mutable<Boolean> naPrelomu = new Mutable<>(false);
- requestedStartPosition = zapocitejPosun(requestedStartPosition,naPrelomu);
- LoadRangeParams newParams = new LoadRangeParams(requestedStartPosition, requestedLoadSize);
- final boolean finalMoved = moved;
- original.loadRange(newParams, new LoadRangeCallback<SQLUkol>() {
- @Override
- public void onResult(@NonNull List<SQLUkol> data) {
- LinkedList<UkolOrHeader> newList = addHeaders(data, finalMoved);
- if (finalMoved && !naPrelomu.value) { // =1=
- newList.removeFirst();
- }
- int loadSize = originalLoadSize;
- if (loadSize > newList.size()) {
- loadSize = newList.size();
- }
- callback.onResult(newList.subList(0, loadSize));
- }
- });
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement