【问题标题】:Ordering Firebase Data in Arraylists/RecyclerView在 Arraylists/RecyclerView 中排序 Firebase 数据
【发布时间】:2018-05-28 02:05:26
【问题描述】:

我正在尝试将数据从 Firebase 数据库提取到 RecyclerView 并正确排序。我已成功将数据导入recyclerview,但排序错误。

我得到了什么: Android Screenshot

基本上是订购它们:

  • 企业

  • 微型

  • 中等

My Firebase DB


它在应用程序中大部分时间都是这样订购的,尽管有一次它订购正确,这让我相信它有点随机,具体取决于哪个任务首先完成。

我最初查找了 arraylist(How to sort ArrayList<Long> in Java in decreasing order?) 的排序,然后查找了 firebase(https://firebase.google.com/docs/database/android/lists-of-data#sort_data) 的排序,但不确定是否还有其他我遗漏的东西?

异步 ​​onDataChange 和 Callback 的组合如何决定哪个先完成?它不是按照我在代码中的顺序来做的。


我希望先按最低价订购,所以:

  1. 中等
  2. 企业

这是我的代码:

注册订阅活动.java:

public class RegisterSubscriptionActivity extends Activity {

    //Firebase Database References
    DatabaseReference mDatabase;
    DatabaseReference mDatabaseMicro;
    DatabaseReference mDatabaseSmall;
    DatabaseReference mDatabaseMedium;
    DatabaseReference mDatabaseLarge;
    DatabaseReference mDatabaseEnterprise;
    DatabaseReference mListItemRef;

    ArrayList subscriptionInfo;

    //Subscription (String) values
    String name, number, price;


    //RECYCLERVIEW ITEMS
    private Context mContext;
    LinearLayout mLinearLayout;
    private RecyclerView mRecyclerView;
    private MyAdapterSubscription mAdapter = new MyAdapterSubscription(this);
    private RecyclerView.LayoutManager mLayoutManager;
    //ArrayList<LinearLayout> linearLayoutList = new ArrayList<LinearLayout>();

    ArrayList<Subscription> myListItems;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register_subscription);

        myListItems = new ArrayList<Subscription>();

        //CALLBACK SO YOU CAN GET THE DATA (FROM) THE ASYNC CALL AND USE IT OUTSIDE OF THE CALL, OTHERWISE IT WILL SHOW AS NULL
        final DataSnapshotCallback callback = new DataSnapshotCallback() {
            @Override
            public void gotDataSnapshot(DataSnapshot snapshot) {
                Subscription subscription = new Subscription(snapshot);
                myListItems.add(subscription);
                mAdapter.updateDataSet(myListItems);
                Log.i("ARRAY LIST CONTENTS", myListItems.get(0).getName());
                Log.i("DATA","Name: " + subscription.getName() + " Price: " + subscription.getPrice() + " Number: " + subscription.getNumber());

            }
    };


        mDatabase = FirebaseDatabase.getInstance().getReference("Subscription");
        mDatabaseMicro = mDatabase.child("Micro");
        mDatabaseSmall = mDatabase.child("Small");
        mDatabaseMedium = mDatabase.child("Medium");
        mDatabaseLarge = mDatabase.child("Large");
        mDatabaseEnterprise = mDatabase.child("Enterprise");

        ValueEventListener eventListener = new ValueEventListener() {

            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                callback.gotDataSnapshot(dataSnapshot);  //CALLS THE CALLBACK AND SENDS THE DATASNAPSHOT TO IT

            }


            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.d("Cancelled",databaseError.toString());
            }
        };  //END of ValueEventListener


        mDatabaseMicro.addListenerForSingleValueEvent(eventListener);
        mDatabaseSmall.addListenerForSingleValueEvent(eventListener);
        mDatabaseMedium.addListenerForSingleValueEvent(eventListener);
        mDatabaseLarge.addListenerForSingleValueEvent(eventListener);
        mDatabaseEnterprise.addListenerForSingleValueEvent(eventListener);
        //Log.i("DATA ITEMS", "NAME: " + name + " / " + "NUMBER: " + number + " / " + "PRICE: " + price); //Will get Null because not in Callback
        //Log.i("LIST OF DATA: ", myListItems.toString()); //Same


        //RECYCLERVIEW STUFF
        mRecyclerView = (RecyclerView) findViewById(R.id.s_recycler_view);

        mContext = getApplicationContext(); // Get the application context

        // Define a layout for RecyclerView
        mLayoutManager = new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false);        
        mRecyclerView.setLayoutManager(mLayoutManager);

        // Set the adapter for RecyclerView
        mRecyclerView.setAdapter(mAdapter);


    } //END OF ONCREATE

    interface DataSnapshotCallback {
        void gotDataSnapshot(DataSnapshot snapshot);
    }

}

订阅.java:

public class Subscription {

    String name, number;
    Long price;

    public Subscription(DataSnapshot dataSnapshot) {

        name = dataSnapshot.child("name").getValue(String.class);
        number = dataSnapshot.child("number").getValue(String.class);
        price = dataSnapshot.child("price").getValue(Long.class);
    }

    public String getName() {
        return name;
    }


    public String getNumber() {
        return number;
    }


    public Long getPrice() {
        return price;
    }


}

MyAdapterSubscription.java:

 class MyAdapterSubscription extends RecyclerView.Adapter<MyAdapterSubscription.ViewHolder> {
    private ArrayList<Subscription> mDataSet = new ArrayList<>();
    private Context mContext;

    MyAdapterSubscription(Context context){
        mContext = context;
    }

     static class ViewHolder extends RecyclerView.ViewHolder{

        TextView nameTV, numberTV, priceTV;
         ViewHolder(View v){
            super(v);
            nameTV = (TextView) v.findViewById(R.id.subNameTV);
            numberTV = (TextView) v.findViewById(R.id.subNumberTV);
            priceTV = (TextView) v.findViewById(R.id.subPriceTV);
        }
    }

    void updateDataSet(ArrayList<Subscription> myArrayList) {
        mDataSet = myArrayList;
        // TODO: 12/13/2017 Sort array list by price. Lowest to highest.
        //Collections.sort(mDataSet);
        // TODO: 12/14/2017 Let it be clickable and link to payment
        notifyDataSetChanged();
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
        // Create a new View
        View v = LayoutInflater.from(mContext).inflate(R.layout.subscription_row_layout,parent,false);
        return new ViewHolder(v);
    }

    //A ViewHolder object stores each of the component views inside the tag field of the Layout, so you can immediately access them without the need to look them up repeatedly.
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Subscription subscription = mDataSet.get(position);
        holder.nameTV.setText(subscription.getName());
        holder.numberTV.setText(subscription.getNumber());
        holder.priceTV.setText(String.format(mContext.getResources().getString(R.string.subscriptionAdapterPrice), subscription.getPrice()));
    }

    @Override
    public int getItemCount(){
        return mDataSet.size();
    }

}

【问题讨论】:

标签: java android sorting arraylist firebase-realtime-database


【解决方案1】:

很简单

因为您使用的是 Firebase 数据存储。

您可以通过其中的这 3 种方法对值进行排序。 orderByChild()
orderByKey() orderByValue()

【讨论】:

    【解决方案2】:

    当 Firebase 按第一个节点 -> 最后一个节点的顺序加载数据时。由于在您的结构中,顺序是企业 ->...-> 小,所以它以这种方式加载数据。因此,如果您已经有 5 个五个固定节点,您可能希望将您的结构重新排序为小型 -> 微型 -> 中型 -> 大型 -> 企业。 您还可以使用 firebase 提供的多个 Sort Data Method
    在您的情况下,由于您只有 5 个节点,如果您将它们读入 ArrayList

    ,您可能只需执行 Collections.sort(arraylist, Collections.reverseOrder())

    【讨论】:

    • 我正在考虑使用 Collections.sort 的方向。我做了以下事情: Collections.sort(mDataSet, new Comparator() { @Override public int compare(Subscription p1, Subscription p2) { return p1.getPrice().intValue()- p2.getPrice().intValue (); // Ascending //比较其两个参数的顺序。返回负整数、零或正整数,因为第一个参数小于、等于或大于第二个。} });
    • 是的,您可以使用 Collections.sort,但由于您只是比较价格,您可以像这样使用 Firebase 的 orderByChild() 方法 ref.orderByChild("price").on("child_added ", function(snapshot) { //对快照做某事 });
    猜你喜欢
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 2017-02-14
    • 1970-01-01
    相关资源
    最近更新 更多