2016-08-30 8 views
0

FirebaseUI ListViewの順序は、ローカルデータモデル(この場合はPerson.class)のプロパティではなく、データベースに含まれる価値...リアルタイムでもそれ以下?注文方法Firebase ListView(FirebaseUI)をカスタムプロパティ(データベース値ではない)で

問題:PHP/mysqlからfirebaseへと広範囲の場所ベースのアプリケーション(ライド共有アプリケーションに似ています)を変換しています。 (私はFirebaseについてとても興奮しています...ところで、私はすでに多くの利点を見てきました)。

私たちの目的のために、アプリは遠くから注文された近くの利用可能なサービスプロバイダを再調査するリストビューを単に表示します。以前は、POSTパラメータとして顧客の緯度と経度を含むPHPリクエストをサーバーに送信していました。サーバーはサービスプロバイダーのJSONリストを送り返します。サーバは、サービスプロバイダの顧客との現在の距離に基づいて結果を注文する数学を行う。また、利用できないサービスプロバイダはまったく返されません。このすべての問題は、ユーザーがまだ「リフレッシュする」必要があることです。

Firebaseのアプローチはこれまでのところ動作していますが、サービスプロバイダのアベイラビリティ(コードを参照)で自分の(FirebaseUI powered)リストビューをフィルタリングすることしかできませんでしたが、リストの注文方法距離によって。

以下のコードは、私が何をしようとしているのかを示しています。 Personクラスは、サービスプロバイダを表します。

だから、Personクラスには変数Person.distanceと、(Firebaseデータベースの)場所とアプリケーションユーザーの電話に現在格納されている場所の間の計算距離を返すgetDistance()メソッドがあるとしましょう。この変数は明らかにデータベースに格納することはできず、相対的であり、ユーザーとサービスプロバイダの両方の場所に依存するため、比較可能な値として使用できます。

リサイクラービューを使用してこれを達成する方法はありますか?私はそれがアダプタの中で何か行われるだろうと思うだろう...しかし、それは既に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からの緯度/経度と人の緯度/経度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クラスの中で、距離に基づいてインデックスを静かに再マップします...しかし、率直に言って、私の頭が痛いです)。

とにかく私はまた、lat/lonの代わりにgeohashを使って、Geofireのような別の解決策を考えました。そうすれば、2つではなく1つの(ソート可能な)ロケーションフィールドのみが存在し、既存のFirebaseクエリメソッドを使用してソートされた(近接によって)リストを取得することができます。まだこれに取り組んでいます。

関連する問題