2016-08-30 6 views
0

Возможно ли иметь заказ FirebaseUI ListView собственностью локальной модели данных (в данном случае Person.class) в отличие от значение, содержащееся в базе данных ... в реальном времени не меньше?Как заказать Firebase ListView (FirebaseUI) с помощью настраиваемого свойства (не значение базы данных)

Проблема: Я конвертирую приложение, основанное на местоположении (похожее на приложение для ridesharing), из PHP/mysql в firebase. (Я очень рад Firebase, кстати ... и я уже видел много преимуществ).

Для наших целей приложение просто отображает список просмотра, находящийся поблизости, и доступные поставщики услуг, заказанные по расстоянию. Это было сделано ранее, отправив PHP-запрос, включая широту и долготу клиента как параметры POST на сервер. Затем сервер отправит список поставщиков услуг JSON. Сервер выполнил бы математическую обработку заказов на основе текущего расстояния от поставщика услуг до клиента. Также ... поставщики услуг, которые недоступны, не возвращаются вообще. Проблема со всем этим заключается в том, что пользователю все еще нужно «потянуть, чтобы обновить».

Подход Firebase работает до сих пор, но я смог только фильтровать мой список (FirebaseUI) по доступности поставщика услуг (см. Код), но я не мог придумать, как заказать список по расстоянию.

В приведенном ниже коде показано, что я пытаюсь сделать. Класс 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) слишком широк для ответа на Stack Overflow. –

ответ

0

Я достиг того, что, как представляется, рабочее решение ... хотя я определенно выбрали для простоты по эффективности. Я не думаю, что я действительно «переписал» что угодно - больше похоже на игру в старую игру «Операция». Во всяком случае ... Вот что я сделал:

1) Сделано для класса Person. Сопоставим, чтобы Collection.sort() работал. В методе compareTo() сортировка выполняется через Person.getDistance(), которая просто вычисляет расстояние между лат/lon от GPS телефона, на котором работает приложение, и lat/lon человека (retreived из базы данных Firebase).

2) Изменен метод GetItem() в FirebaseListActivity следующим образом:

@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. Все еще работаю над этим.