如何在Realm Database Android中使用LIMIT查询获取记录数 [英] How to get Number of Records using LIMIT Query in Realm Database android

查看:173
本文介绍了如何在Realm Database Android中使用LIMIT查询获取记录数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经用Realm Database Plugin实施了我的新项目. 我有Pagination的功能,记录数为20. 因此,如何使用Realm Query来获取20条记录. 我搜索了,但是没有任何解决方法.

I have Implemented my new project with Realm Database Plugin. I have a functionality of Pagination with Number of Record as 20. So How can I fetch 20 Record using Realm Query . I searched, but did not get any solution.

推荐答案

我写了

常见错误:无缘无故地试图对RealmResults<T>进行分页或限制结果的数量"

Common mistake: attempting to paginate a RealmResults<T> or "limit the number of results in it" for no valid reason whatsoever

我见过有人试图对RealmResults进行分页,或我如何进行极限查询".问的第一个问题是您为什么还要尝试这样做. 通常是因为要限制RealmResults,您只需不必将其索引到任意阈值以上即可.

I’ve seen people on SO attempting to paginate a RealmResults, or "how do I do a limit query". The first question asked is why are you even trying to do that. Mostly because to limit a RealmResults, you simply have to not index it above your arbitrary threshold.

为了清楚起见:RealmResults不包含任何元素.它包含评估查询结果的方法.仅当您调用realmResults.get(i)时才从领域中获取元素,并且一次仅返回该单个元素.它就像一个游标,除了它是一个列表.因此,限制"它并分页"是没有意义的.如果确实需要它,则限制索引.

To make it clear: RealmResults does NOT contain any elements. It contains the means to evaluate the results of the query. The element is obtained from the Realm only when you call realmResults.get(i), and only that single element is returned at a time. It’s like a Cursor, except it’s a List. Therefore, "limiting" it and "paginating" it doesn’t make sense. If you really need it, then limit your index.

因此,如果您确实需要分页,请编写一个接收RealmResults的适配器,跟踪当前页面,显示

So if you really need pagination, then write an adapter that receives a RealmResults, keeps track of the current page, shows

int pageSize = results.size() - pageIndex*20; 
if(pageSize < 0) {
    pageSize = 0;
}
pageSize = Math.min(pageSize, 20); 

getItemCount()中的元素,并显示结果中[20*pageIndex + 0...19]中的元素.

elements in getItemCount(), and displays elements from [20*pageIndex + 0...19] from your results.

编写适配器时,请不要忘记将保存在字段变量中的更改侦听器添加/删除到调用notifyDataSetChanged()的结果中.

When you write your adapter, don't forget to add/remove a change listener kept in a field variable to your results which calls 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,尽管我尚未对其进行测试.

This should do it for Realm 1.2.0, although I haven't tested it.

这篇关于如何在Realm Database Android中使用LIMIT查询获取记录数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆