如何使用分页库从数据库中获取数据以在地图上显示数据

时间:2018-04-09 05:03:54

标签: android google-maps retrofit2 android-paging

我有一个大约有50,000纬度和经度的服务器数据库。我正在使用Retrofit 2从数据库中获取数据。我想以组的形式获取数据并在地图上显示它们。即在一个请求中,我想仅获取500个纬度和经度并在地图上显示它们,并且该过程应该继续,直到所有标记都在地图上绘制。我想使用分页在一个页面请求中的500个位置获取该数据。任何人都可以帮助我实现这个目标。谢谢你的帮助。

public interface Api {
String BASE_URL = "http://172.20.10.4/demophp/";

@GET("locations.php")
Call<List<CoordinatesVM>> getCoordinates();
}

CoordinaatesDatabase.java

@Database(entities = {CoordinatesVM.class},version = 1)
public abstract class CoordinatesDatabase extends RoomDatabase{

private static CoordinatesDatabase db;
public abstract CoordinatesDAO coodinatesDAO();
private static final String COORDINATES_DB = "CoordinatesVM.db";

public static CoordinatesDatabase getAppDatabase(Context context){
    if (db == null) {
        db = Room.databaseBuilder(context.getApplicationContext(),CoordinatesDatabase.class, COORDINATES_DB).build();
        Toast.makeText(context, "Database is created..!! ", Toast.LENGTH_SHORT).show();
    }else {
        Toast.makeText(context, "Database is already created..!", Toast.LENGTH_SHORT).show();
    }
    return db;
}
}

CoordinatesDAO

@Dao
public interface CoordinatesDAO  {

@Insert(onConflict = REPLACE)
void insertLocation(CoordinatesVM... coordinates);

@Query("SELECT * FROM CoordinatesVM")
List<CoordinatesVM> getAll();
}

CoordinatesVm.java

@Entity
public class CoordinatesVM  {

@SerializedName("Id")
@Expose
@ColumnInfo(name = "Id")
@PrimaryKey(autoGenerate = true)
@NonNull
private int id;

@SerializedName("Latitude")
@Expose
@ColumnInfo(name = "Latitude")
private String latitude;

@SerializedName("Longitude")
@Expose
@ColumnInfo(name = "Longitude")
private String longitude;

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getLatitude() {
    return latitude;
}

public void setLatitude(String latitude) {
    this.latitude = latitude;
}

public String getLongitude() {
    return longitude;
}

public void setLongitude(String longitude) {
    this.longitude = longitude;
}

}

2 个答案:

答案 0 :(得分:0)

如果这是您自己的服务器,则应更改端点以接受具有startFrom和limit的查询。如果这样做,您可以随时进行API调用。如果要在地图上显示所有前一个查询后再查询。或者您可以进行多次呼叫并在本地保存响应并根据需要显示它们。 如果您使用任何公共API。您可以创建一个firebase云功能,该功能将获取数据并将其存储在firebase数据库中,您可以使用firebase API(优惠限制,订购等)查询数据,这将更快。

你可以使用这样的东西

    val starting = 0
        PublishProcessor<ApiRequest> requestPublisher = PublishProcessor.create<ApiRequest>()
    requestPublisher.subscribe({request->
       makeApiCall(request).subscribe({list->
    if(list.size<500 || starting == 50000){
     requestPublisher.onComplete()
}else{
  //at this point you can save them locally 
  requestPublisher.onNext(request(starting,500))
}
},{error-> requestPublisher.onError(error)})
    },{error-> },{complete->})
requestPublisher.onNext(0,500)

答案 1 :(得分:0)

您可以使用此类并在您的活动或片段中实现它以进行分页。

public abstract class EndlessRecyclerViewScrollListener extends RecyclerView.OnScrollListener {

  private int visibleThreshold = 5;

  private int currentPage = 0;

  private int previousTotalItemCount = 0;

  private boolean loading = true;

  private int startingPageIndex = 0;

  RecyclerView.LayoutManager mLayoutManager;

  public EndlessRecyclerViewScrollListener(LinearLayoutManager layoutManager) {
    this.mLayoutManager = layoutManager;
  }

  public EndlessRecyclerViewScrollListener(GridLayoutManager layoutManager) {
    this.mLayoutManager = layoutManager;
    visibleThreshold = visibleThreshold * layoutManager.getSpanCount();
  }

  public EndlessRecyclerViewScrollListener(StaggeredGridLayoutManager layoutManager) {
    this.mLayoutManager = layoutManager;
    visibleThreshold = visibleThreshold * layoutManager.getSpanCount();
  }

  public int getLastVisibleItem(int[] lastVisibleItemPositions) {
    int maxSize = 0;
    for (int i = 0; i < lastVisibleItemPositions.length; i++) {
      if (i == 0) {
        maxSize = lastVisibleItemPositions[i];
      }
      else if (lastVisibleItemPositions[i] > maxSize) {
        maxSize = lastVisibleItemPositions[i];
      }
    }
    return maxSize;
  }

  @Override
  public void onScrolled(RecyclerView view, int dx, int dy) {
    int lastVisibleItemPosition = 0;
    int totalItemCount = mLayoutManager.getItemCount();

    if (mLayoutManager instanceof StaggeredGridLayoutManager) {
      int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(null);

      lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions);
    } else if (mLayoutManager instanceof GridLayoutManager) {
      lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition();
    } else if (mLayoutManager instanceof LinearLayoutManager) {
      lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition();
    }


    if (totalItemCount < previousTotalItemCount) {
      this.currentPage = this.startingPageIndex;
      this.previousTotalItemCount = totalItemCount;
      if (totalItemCount == 0) {
        this.loading = true;
      }
    }

    if (loading && (totalItemCount > previousTotalItemCount)) {
      loading = false;
      previousTotalItemCount = totalItemCount;
    }

    if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) {
      currentPage++;
      onLoadMore(currentPage, totalItemCount, view);
      loading = true;
    }
  }

  // Call this method whenever performing new searches
  public void resetState() {
    this.currentPage = this.startingPageIndex;
    this.previousTotalItemCount = 0;
    this.loading = true;
  }

  // Defines the process for actually loading more data based on page
  public abstract void onLoadMore(int page, int totalItemsCount, RecyclerView view);

}

如果这样使用

 EndlessRecyclerViewScrollListener scrollListener = new EndlessRecyclerViewScrollListener(manager) {
            @Override
            public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
                // call your api
            }
        };
        yourRecyclerView.addOnScrollListener(scrollListener);