我已经用Realm Database Plugin
. 我有一个Pagination
记录数为 20 的功能。那么如何使用 Realm Query 获取 20 条记录。我搜索了,但没有得到任何解决方案。
问问题
2082 次
1 回答
2
我写了一篇关于 Realm 的文章,我特别提到了
常见错误:无正当理由试图对 a 进行分页
RealmResults<T>
或“限制其中的结果数量”
我在 SO 上看到有人试图对 RealmResults 进行分页,或者“我如何进行限制查询”。问的第一个问题是你为什么要这样做。主要是因为要限制 RealmResults,您只需要将其索引到您的任意阈值之上。
为了清楚起见:RealmResults 不包含任何元素。它包含评估查询结果的方法。仅当您调用 realmResults.get(i) 时才从 Realm 获取元素,并且一次仅返回该单个元素。它就像一个光标,除了它是一个列表。因此,“限制”它和“分页”它是没有意义的。如果你真的需要它,那么限制你的索引。
因此,如果您确实需要分页,那么编写一个接收 a 的适配器,RealmResults
跟踪当前页面,显示
int pageSize = results.size() - pageIndex*20;
if(pageSize < 0) {
pageSize = 0;
}
pageSize = Math.min(pageSize, 20);
中的元素getItemCount()
,并显示[20*pageIndex + 0...19]
结果中的元素。
当您编写适配器时,不要忘记将保存在字段变量中的更改侦听器添加/删除到调用notifyDataSetChanged()
.
所以,就像,
/*
* Copyright 2016 Realm Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.realm;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
/**
* The RealmPagedRecyclerViewAdapter class is an abstract utility class for binding RecyclerView UI elements to Realm data.
* <p>
* This adapter will automatically handle any updates to its data and call notifyDataSetChanged() as appropriate.
* Currently there is no support for RecyclerView's data callback methods like notifyItemInserted(int), notifyItemRemoved(int),
* notifyItemChanged(int) etc.
* It means that, there is no possibility to use default data animations.
* <p>
* The RealmAdapter will stop receiving updates if the Realm instance providing the {@link OrderedRealmCollection} is
* closed.
*
* @param <T> type of {@link RealmModel} stored in the adapter.
* @param <VH> type of RecyclerView.ViewHolder used in the adapter.
*/
public abstract class RealmPagedRecyclerViewAdapter<T extends RealmModel, VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
protected final LayoutInflater inflater;
@NonNull
protected final Context context;
private final boolean hasAutoUpdates;
private final RealmChangeListener listener;
@Nullable
private OrderedRealmCollection<T> adapterData;
private int pageIndex = 0;
public RealmRecyclerViewAdapter(@NonNull Context context, @Nullable OrderedRealmCollection<T> data, boolean autoUpdate) {
//noinspection ConstantConditions
if (context == null) {
throw new IllegalArgumentException("Context can not be null");
}
this.context = context;
this.adapterData = data;
this.inflater = LayoutInflater.from(context);
this.hasAutoUpdates = autoUpdate;
// Right now don't use generics, since we need maintain two different
// types of listeners until RealmList is properly supported.
// See https://github.com/realm/realm-java/issues/989
this.listener = hasAutoUpdates ? new RealmChangeListener() {
@Override
public void onChange(Object results) {
notifyDataSetChanged();
}
} : null;
}
public void updatePage(int index) {
this.pageIndex = index;
notifyDataSetChanged();
}
@Override
public void onAttachedToRecyclerView(final RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
if (hasAutoUpdates && isDataValid()) {
//noinspection ConstantConditions
addListener(adapterData);
}
}
@Override
public void onDetachedFromRecyclerView(final RecyclerView recyclerView) {
super.onDetachedFromRecyclerView(recyclerView);
if (hasAutoUpdates && isDataValid()) {
//noinspection ConstantConditions
removeListener(adapterData);
}
}
/**
* Returns the current ID for an item. Note that item IDs are not stable so you cannot rely on the item ID being the
* same after notifyDataSetChanged() or {@link #updateData(OrderedRealmCollection)} has been called.
*
* @param index position of item in the adapter.
* @return current item ID.
*/
@Override
public long getItemId(final int index) {
return index;
}
@Override
public int getItemCount() {
if(!isDataValid()) {
return 0;
}
int pageSize = results.size() - pageIndex*20;
if(pageSize < 0) {
pageSize = 0;
}
pageSize = Math.min(pageSize, 20);
return pageSize;
}
/**
* Returns the item associated with the specified position.
* Can return {@code null} if provided Realm instance by {@link OrderedRealmCollection} is closed.
*
* @param index index of the item.
* @return the item at the specified position, {@code null} if adapter data is not valid.
*/
@Nullable
public T getItem(int index) {
//noinspection ConstantConditions
if(!isDataValid()) {
return null;
}
return adapterData.get(index + 20*pageIndex) : null;
}
/**
* Returns data associated with this adapter.
*
* @return adapter data.
*/
@Nullable
public OrderedRealmCollection<T> getData() {
return adapterData;
}
/**
* Updates the data associated to the Adapter. Useful when the query has been changed.
* If the query does not change you might consider using the automaticUpdate feature.
*
* @param data the new {@link OrderedRealmCollection} to display.
*/
public void updateData(@Nullable OrderedRealmCollection<T> data) {
if (hasAutoUpdates) {
if (adapterData != null) {
removeListener(adapterData);
}
if (data != null) {
addListener(data);
}
}
this.adapterData = data;
notifyDataSetChanged();
}
private void addListener(@NonNull OrderedRealmCollection<T> data) {
if (data instanceof RealmResults) {
RealmResults realmResults = (RealmResults) data;
//noinspection unchecked
realmResults.addChangeListener(listener);
} else if (data instanceof RealmList) {
RealmList realmList = (RealmList) data;
//noinspection unchecked
realmList.realm.handlerController.addChangeListenerAsWeakReference(listener);
} else {
throw new IllegalArgumentException("RealmCollection not supported: " + data.getClass());
}
}
private void removeListener(@NonNull OrderedRealmCollection<T> data) {
if (data instanceof RealmResults) {
RealmResults realmResults = (RealmResults) data;
realmResults.removeChangeListener(listener);
} else if (data instanceof RealmList) {
RealmList realmList = (RealmList) data;
//noinspection unchecked
realmList.realm.handlerController.removeWeakChangeListener(listener);
} else {
throw new IllegalArgumentException("RealmCollection not supported: " + data.getClass());
}
}
private boolean isDataValid() {
return adapterData != null && adapterData.isValid();
}
}
这应该适用于 Realm 1.2.0,虽然我还没有测试过。
于 2016-09-02T11:30:51.110 回答