Advertisement
Grejt_cz

MyDatasource.java

May 13th, 2018
639
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.92 KB | None | 0 0
  1. package cz.grejtCZ.ukolnicek.android.headeredList;
  2.  
  3. import android.arch.lifecycle.LiveData;
  4. import android.arch.paging.DataSource;
  5. import android.arch.paging.PositionalDataSource;
  6. import android.support.annotation.NonNull;
  7.  
  8. import org.joda.time.LocalDate;
  9.  
  10. import java.util.LinkedList;
  11. import java.util.List;
  12.  
  13. import cz.grejtCZ.ukolnicek.android.sql.DMO;
  14. import cz.grejtCZ.ukolnicek.android.sql.SQLUkol;
  15.  
  16. /**
  17.  * Hází mezi úkoly hlavičky s datem. úkoly musí být seřazeny podle data.
  18.  * Adds Headers between Ukols. Ukols have to be sorted by date.
  19.  */
  20.  
  21. public class MyDatasource extends PositionalDataSource<UkolOrHeader> {
  22.     private final PositionalDataSource<SQLUkol> original;
  23.     private long listID;
  24.     private List<DateCount> dateCounts;
  25.     private int totalHeaders;
  26.  
  27.     public MyDatasource(PositionalDataSource<SQLUkol> original, long listID) {
  28.         this.original = original;
  29.         this.listID = listID;
  30.     }
  31.     //<editor-fold name="Invalidating">
  32.  
  33.     @Override
  34.     public void addInvalidatedCallback(@NonNull InvalidatedCallback onInvalidatedCallback) {
  35.         original.addInvalidatedCallback(onInvalidatedCallback);
  36.     }
  37.  
  38.     @Override
  39.     public void removeInvalidatedCallback(@NonNull InvalidatedCallback onInvalidatedCallback) {
  40.         original.removeInvalidatedCallback(onInvalidatedCallback);
  41.     }
  42.  
  43.     @Override
  44.     public void invalidate() {
  45.         original.invalidate();
  46.     }
  47.  
  48.     @Override
  49.     public boolean isInvalid() {
  50.         return original.isInvalid();
  51.     }
  52.  
  53.     //</editor-fold>
  54.     public static class Factory extends DataSource.Factory<Integer, UkolOrHeader> {
  55.  
  56.         private DataSource.Factory orig;
  57.         private long listID;
  58.  
  59.         public Factory(DataSource.Factory<Integer, SQLUkol> orig, long listID) {
  60.             this.orig = orig;
  61.             this.listID = listID;
  62.         }
  63.  
  64.         @Override
  65.         public DataSource<Integer, UkolOrHeader> create() {
  66.             return new MyDatasource((PositionalDataSource<SQLUkol>) orig.create(), listID);
  67.         }
  68.     }
  69.  
  70.     /**
  71.      * dostane seznam ukolu a prida mezi nej hlavicky. takze musi dostat seznam s predchozim ukolem nez je prvni zadany
  72.      * gets list of Ukols and adds headers in between, so it needs to receive the Ukol before requested as well.
  73.      */
  74.     private static LinkedList<UkolOrHeader> addHeaders(List<SQLUkol> list, boolean moved) {
  75.         if (list.size() == 0) {
  76.             return new LinkedList<>();
  77.         }
  78.         LinkedList<UkolOrHeader> vrat = new LinkedList<>();
  79.         LocalDate predchozi = null;
  80.         for (int i = 0; i < list.size(); i++) {
  81.             SQLUkol item = list.get(i);
  82.             LocalDate date = item.getDate();
  83.  
  84.             if(i == 0){
  85.                 if (!moved){
  86.                     vrat.add(new Header(date));
  87.                 }
  88.             }else {
  89.                 if (date != null && (predchozi == null || date.isAfter(predchozi))){
  90.                     vrat.add(new Header(date));
  91.                 }
  92.             }
  93.             vrat.add(new UkolInList(item));
  94.             predchozi = date;
  95.         }
  96.         return vrat;
  97.     }
  98.  
  99.     //<editor-fold name="Mutable>
  100.     private static class Mutable<T> {
  101.         public T value;
  102.  
  103.         public Mutable() {
  104.         }
  105.  
  106.         public Mutable(T value) {
  107.             this.value = value;
  108.         }
  109.     }
  110.     //</editor-fold>
  111.  
  112.     /**
  113.      * vrati index v databazi, bez headeru
  114.      * EN: Calculate offset
  115.      * returns index of Ukol in database (without headers) corresponding to the given one (from displayed list, with headers)
  116.      * @param naPrelomu is set to true if start is pointing to Header, so you do not have to romove one Ukol later (see =1=)
  117.      */
  118.     private int zapocitejPosun(int start, Mutable<Boolean> naPrelomu/*EN: onEdge*/) {
  119.         int i = 0;
  120.         int pocet = 0;
  121.  
  122.         while (pocet < start && i < dateCounts.size()) {
  123.  
  124.             pocet += 1 + dateCounts.get(i).count;
  125.             i++;
  126.             if (pocet == start){
  127.                 naPrelomu.value = true;
  128.             }
  129.         }
  130.  
  131.         return start - i;
  132.     }
  133.  
  134. /**
  135.      * vrati index v seznamu odpovidajici ukolu na danem indexy v seznamu v databazni
  136.      * EN: calculate back offset
  137.      * gets index of Ukol in Database (no headers) and returns idex in displeyed list (headers)
  138.      *
  139.      * @param start index ukolu v databazi
  140.      * @return index v headrovanem seznamu
  141.      */
  142.     private int posunZpet(int start) {
  143.         int hederu = 0;
  144.         int i = -1;
  145.         while (i < start) {
  146.             i += dateCounts.get(hederu).count;
  147.             hederu++;
  148.         }
  149.         return start + hederu;
  150.     }
  151.  
  152.  
  153.     @Override
  154.     public void loadInitial(@NonNull LoadInitialParams params, @NonNull final LoadInitialCallback callback) {
  155.         int requestedStartPosition = params.requestedStartPosition;
  156.         int requestedLoadSize = params.requestedLoadSize;
  157.         final int originalLoadSize = requestedLoadSize;
  158.         int pageSize = params.pageSize;
  159.         boolean placeholdersEnabled = params.placeholdersEnabled;
  160.  
  161.         boolean moved = false;
  162.  
  163.         //shifts loaded area, so that we know if there is a header on the start of requested area
  164.         if (requestedStartPosition != 0) {
  165.             requestedStartPosition--;
  166.             requestedLoadSize++;
  167.             pageSize++;
  168.             moved = true;
  169.         }
  170.  
  171.         dateCounts = DMO.getDao().getDateCount(listID);
  172.         totalHeaders = dateCounts.size();
  173.         final Mutable<Boolean> naPrelomu = new Mutable<>(false);
  174.         requestedStartPosition = zapocitejPosun(requestedStartPosition,naPrelomu);
  175.  
  176.  
  177.         LoadInitialParams newParams = new LoadInitialParams(requestedStartPosition, requestedLoadSize, pageSize, placeholdersEnabled);
  178.         final boolean finalMoved = moved;
  179.         original.loadInitial(newParams, new LoadInitialCallback<SQLUkol>() {
  180.             @Override
  181.             public void onResult(@NonNull List<SQLUkol> data, int position, int totalCount) {
  182.                LinkedList<UkolOrHeader> newList = addHeaders(data, finalMoved);
  183.                 int newPosition =  posunZpet(position);
  184.  
  185.                 if (finalMoved && !naPrelomu.value) { // =1=
  186.                     newList.removeFirst();
  187.                 }
  188.  
  189.                 if (newList.get(0) instanceof Header){
  190.                     newPosition -= 1;
  191.                 }
  192.  
  193.                 int loadSize = originalLoadSize;
  194.  
  195.                 if (loadSize > newList.size()) {
  196.                     loadSize = newList.size();
  197.                 }
  198.  
  199.                 int total = totalCount + totalHeaders;
  200.                 callback.onResult(newList.subList(0, loadSize),newPosition, total);
  201.             }
  202.  
  203.             @Override
  204.             public void onResult(@NonNull List<SQLUkol> data, int position) {
  205.                 LinkedList<UkolOrHeader> newList = addHeaders(data, finalMoved);
  206.                 int newPosition =  posunZpet(position);
  207.  
  208.                 if (finalMoved && !naPrelomu.value) { // =1=
  209.                     newList.removeFirst();
  210.                 }
  211.  
  212.                 if (newList.get(0) instanceof Header){
  213.                     newPosition -= 1;
  214.                 }
  215.  
  216.                 int loadSize = originalLoadSize;
  217.  
  218.                 if (loadSize > newList.size()) {
  219.                     loadSize = newList.size();
  220.                 }
  221.  
  222.                 callback.onResult(newList.subList(0, loadSize),newPosition);
  223.             }
  224.         });
  225.     }
  226.  
  227.     @Override
  228.     public void loadRange(@NonNull LoadRangeParams params, @NonNull final LoadRangeCallback callback) {
  229.         int requestedStartPosition = params.startPosition;
  230.         int requestedLoadSize = params.loadSize;
  231.         final int originalLoadSize = requestedLoadSize;
  232.  
  233.         boolean moved = false;
  234.  
  235.         //shifts loaded area, so that we know if there is a header on the start of requested area
  236.         if (requestedStartPosition != 0) {
  237.             requestedStartPosition--;
  238.             requestedLoadSize++;
  239.             moved = true;
  240.         }
  241.  
  242.         final Mutable<Boolean> naPrelomu = new Mutable<>(false);
  243.         requestedStartPosition = zapocitejPosun(requestedStartPosition,naPrelomu);
  244.  
  245.         LoadRangeParams newParams = new LoadRangeParams(requestedStartPosition, requestedLoadSize);
  246.         final boolean finalMoved = moved;
  247.         original.loadRange(newParams, new LoadRangeCallback<SQLUkol>() {
  248.  
  249.             @Override
  250.             public void onResult(@NonNull List<SQLUkol> data) {
  251.                 LinkedList<UkolOrHeader> newList = addHeaders(data, finalMoved);
  252.  
  253.                 if (finalMoved && !naPrelomu.value) { // =1=
  254.                     newList.removeFirst();
  255.                 }
  256.  
  257.                 int loadSize = originalLoadSize;
  258.  
  259.                 if (loadSize > newList.size()) {
  260.                     loadSize = newList.size();
  261.                 }
  262.  
  263.                 callback.onResult(newList.subList(0, loadSize));
  264.             }
  265.         });
  266.     }
  267. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement