簡體   English   中英

如何在Realm數據庫android中使用LIMIT查詢獲取記錄數

[英]How to get Number of Records using LIMIT Query in Realm Database android

我已經使用Realm Database Plugin實現了我的新項目。 我具有Pagination功能,記錄數為20。因此,如何使用Realm Query獲取20條記錄。 我進行了搜索,但沒有得到任何解決方案。

我寫了一篇關於Realm的文章 ,我特別提到

常見錯誤RealmResults<T>試圖對RealmResults<T>進行分頁或“限制其中的結果數”


我見過有人試圖分頁RealmResults,或“我如何進行極限查詢”。 問的第一個問題是您為什么還要嘗試這樣做。 通常是因為要限制RealmResults,您只需不必將其索引到任意閾值以上即可。

明確說明:RealmResults不包含任何元素。 它包含評估查詢結果的方法。 僅當您調用realmResults.get(i)時才從領域獲得該元素,並且一次僅返回該單個元素。 它就像一個游標,除了它是一個列表。 因此,“限制”它並“分頁”是沒有意義的。 如果確實需要,請限制索引。

因此,如果您確實需要分頁,請編寫一個接收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, 應該可以做到這一點,盡管我尚未對其進行測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM