2016-08-30 40 views
0

FirebaseUI ListView是否可以通過本地數據模型(在本例中爲Person.class)的屬性進行自我訂購包含在數據庫中的值......實時不低於?如何通過自定義屬性(非數據庫值)訂購Firebase ListView(FirebaseUI)

問題:我將基於位置的應用程序(類似於搭車應用程序)從PHP/mysql轉換爲firebase。 (順便說一句,我對Firebase感到非常興奮,而且我已經看到了很多優勢)。

就我們的目的而言,該應用程序只是簡單地顯示列表視圖,代表按距離排序的附近和可用服務提供商。這是通過向服務器發送包括客戶經緯度在內的PHP請求作爲POST參數來完成的。然後服務器將發回一個JSON服務提供者列表。服務器會根據服務提供商與客戶的當前距離來計算結果的數學運算。另外...不可用的服務提供商根本不會返回。所有這一切的問題是用戶仍然需要「拉動刷新」。

雖然Firebase方法到目前爲止還在工作,但我只能根據服務提供商的可用性(請參閱代碼)過濾我的(FirebaseUI支持的)listview,但我一直無法想到如何訂購該列表由距離。

下面的代碼顯示了我想要做的事情。 Person類表示服務提供者。

因此,讓我們假設Person類具有可變的Person.distance和getDistance()方法,該方法返回其位置(來自Firebase數據庫)與當前存儲在應用用戶手機中的位置之間的計算距離。這個變量顯然不能存儲在數據庫中,因爲它是相對的,並且取決於用戶和服務提供者的位置,所以用作可比較的值。

有沒有辦法讓這個使用回收視圖,而不是?我會假設它將在適配器內部完成......但是這些都已經包含在FirebaseUI中了......而且我還沒有足夠的編碼來重新編寫Android庫類。謝謝你的幫助。

相關代碼(正常工作......這不是問題......請閱讀後第一):

ref = FirebaseDatabase.getInstance().getReference().child("person"); 

    Query orderedByAvail_Query = ref.orderByChild("available").equalTo(true); 

    FirebaseListAdapter<Person> fireAdapter = new FirebaseListAdapter<Person>(getActivity(), 
      Person.class, R.layout.single_row, orderedByAvail_Query) { 
     @Override 
     protected void populateView(View v, Person person, int position) { 

      TextView name_title = (TextView) v.findViewById(R.id.Nickname); 
      name_title.setText(person.getNickname()); 

      if (person.getAvail()){ 
       name_title.setBackgroundColor(Color.GREEN); 
      } else { 
       name_title.setBackgroundColor(Color.WHITE); 
      } 




     } 
    }; 

     // Arraylist<Person> tempList4Sorting = new ArrayList<Person>; 

     // for (i=1 to fireAdapter.size){ 
     // tempList4Sorting.add(fireAdapter.getItem(i); 
     // i++; 
     // } 

     // Collections.sort(tempList4Sorting, Person.distance, DESCENDING); 

     // fireAdapter.clearItems(); 
     // 
     // put sorted items back into the adapter using another for loop 

     // fireAdapter.notifyDataSetChanged (?) 


    setListAdapter(fireAdapter); 
+1

FirebaseUI中的適配器只能根據Firebase返回它們的順序(基於您指定的查詢)對項目進行排序。如果這不能滿足您的需求,您將不得不創建自己的適配器。 FirebaseUI是開源的,因此適配器可以用作靈感/作爲起點。 –

+0

我已經開始嘗試這個了,謝謝推動。 –

+1

不錯。如果您遇到困難,請使用最少代碼複製粘貼位置,然後嘗試提供幫助。我要投票結束這個問題,因爲編寫這樣的適配器(雖然很有趣 - 我在FirebaseUI中編寫了這些適配器)對於堆棧溢出的答案有點太寬泛。 –

回答

0

我取得了什麼似乎是一個有效的解決方案......雖然我絕對選擇爲了簡化而不是效率。我不認爲我真的「重寫了」任何東西 - 更像是玩舊遊戲,「操作」。無論如何...這是我做的:

1)使Person類實現Comparable,以便Collection.sort()將工作。在compareTo()方法中,排序是通過Person.getDistance()來完成的,該方法簡單地計算應用程序運行的手機的GPS的經緯度與人的經緯度之間的距離(retreived來自Firebase數據庫)。

2)改變在FirebaseListActivity爲getItem()方法如下:

@Override 
public T getItem(int position) { 
    Log.i("XXX", "getItem() was called"); 


    // put all (parsed) list items into an array 

    ArrayList<Person> temp_person_list = new ArrayList(); 

    for (int i = 1; i<=(mSnapshots.getCount()); i++){ 

     temp_person_list.add((Person) parseSnapshot(mSnapshots.getItem(i-1))); 

    } 

    // sort the array based on distance property 
    Collections.sort(temp_person_list); 


    // return the originally desired position 
    return (T) temp_person_list.get(position); 

} 

我知道這在原則上是可怕的......(我敢肯定有更好的方式是添加另一個潛在的ArrayList在FirebaseArray類內部,默默地根據距離重新映射索引...但坦率地說,這使我的頭受傷)。

無論如何...我也考慮過另一種可能的解決方案(如Geofire) - 使用geohash代替lat/lon。這樣,只有一個(可排序的)位置字段而不是兩個...並且可能會查詢使用現有Firebase查詢方法實現已排序(按鄰近度)列表。仍在努力。

相關問題