2017-01-17 2 views
2

Мне нужно получить позицию, используя LocationManager, выполнить поиск в моей базе данных царства и, наконец, обмануть RealmRecyclerViewAdapter, используя adapter.notifyDataSetChanged(). Так что я сделал это Observable:Запрос Realm не обновляет мой адаптер

private void getLocation() { 
    int GPSoff = -1; 

    try { 
     GPSoff = Settings.Secure.getInt(getActivity().getContentResolver(), Settings.Secure.LOCATION_MODE); 
    } catch(Settings.SettingNotFoundException e) { 
     e.printStackTrace(); 
    } 
    if(GPSoff == 0) { 
     new AlertDialog.Builder(getActivity()).setTitle("Couldn't get your current location") 
       .setMessage("Do you want to enable location?") 
       .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int which) { 
         Intent onGPS = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
         startActivity(onGPS); 
        } 
       }) 
       .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int which) { 
         // do nothing 
        } 
       }) 
       .show(); 
    } 
    Observable.create(new Observable.OnSubscribe<Location>() { 
     LocationManager mLocationManager; 

     public void call(final Subscriber<? super Location> subscriber) { 
      final LocationListener listener = new LocationListener() { 
       @Override 
       public void onLocationChanged(Location location) { 
        if(location != null) { 
         Log.v("Location Changed", location.getLatitude() + " and " + location.getLongitude()); 
         subscriber.onNext(location); 
         try { 
          mLocationManager.removeUpdates(this); 
          subscriber.onCompleted(); 
         } catch(SecurityException e) { 
          e.printStackTrace(); 
         } 
        } 
       } 

       @Override 
       public void onStatusChanged(String provider, int status, Bundle extras) { 
       } 

       @Override 
       public void onProviderEnabled(String provider) { 
       } 

       @Override 
       public void onProviderDisabled(String provider) { 
       } 
      }; 
      mLocationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE); 
      try { 
       Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
       if(location != null && location.getTime() > Calendar.getInstance().getTimeInMillis() - 2 * 60 * 1000) { 
        subscriber.onNext(location); 
        subscriber.onCompleted(); 
       } else { 
        getActivity().runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          try { 
           // .requestLocationUpdates(LocationManager.GPS_PROVIDER, 
           //  GPS_TIME_INTERVAL, GPS_DISTANCE, GPSListener); 
           mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 10000, listener); 
           mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 10000, listener); 
          } catch(SecurityException e) { 
           e.printStackTrace(); 
          } 
         } 
        }); 
       } 
      } catch(SecurityException e) { 
       e.printStackTrace(); 
      } 
     } 
    }).subscribeOn(Schedulers.newThread()).subscribe(new Subscriber<Location>() { 
     @Override 
     public void onCompleted() { 
      logThreadSignature(); 
      getActivity().runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        nearbs = realm.where(Airport.class) 
          .greaterThanOrEqualTo("latitudeDeg", (latitude - 0.5)) 
          .lessThanOrEqualTo("latitudeDeg", (latitude + 0.5)) 
          .greaterThanOrEqualTo("longitudeDeg", longitude - 0.5) 
          .lessThanOrEqualTo("longitudeDeg", longitude + 0.5) 
          .findAllAsync(); 
        logThreadSignature(); 
        adapter.notifyDataSetChanged(); 
       } 
      }); 
     } 

     @Override 
     public void onError(Throwable e) { 
      e.printStackTrace(); 
     } 

     @Override 
     public void onNext(Location location) { 
      latitude = location.getLatitude(); 
      longitude = location.getLongitude(); 
     } 
    }); 
} 

проблема заключается в том, что я не вижу никаких изменений в моем адаптере. Код этого адаптера:

public class AirportsAdapter 
     extends RealmRecyclerViewAdapter<Airport, RecyclerView.ViewHolder> 
     implements Filterable { 
    Context context; 
    String countryName; 
    public static final int FILTER_MODE_A = 0; 
    public static final int FILTER_MODE_B = 1; 
    OrderedRealmCollection<Airport> listAirports; 
    RealmResults<Airport> nearby; 
    Realm realm; 

    int NEARBY = 0; 
    int AIRPORTS = 2; 
    int nearbySize; 
    int COUNTRY = 3; 
    boolean countryFlag = false; 
    int ALL = 1; 

    public AirportsAdapter(Context context, OrderedRealmCollection<Airport> airports, RealmResults<Airport> nearby, Realm realm) { 
     super(context, airports, true); 
     this.context = context; 
     this.listAirports = airports; 
     this.realm = realm; 
     this.nearby = nearby; 

     Log.d("nearv", String.valueOf(nearby.size())); 
    } 

    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     if(viewType == NEARBY) { 
      View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.input_custom_item, parent, false); 
      MenuHolder menuHolder = new MenuHolder(view); 
      return menuHolder; 
     } else if(viewType == ALL) { 
      View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.input_custom_item, parent, false); 
      MenuHolder menuHolder = new MenuHolder(view); 
      return menuHolder; 
     } 

     if(viewType == COUNTRY) { 
      View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.input_custom_item, parent, false); 
      MenuHolder menuHolder = new MenuHolder(view); 
      return menuHolder; 
     } else { 
      View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.airport_show, parent, false); 
      AirportClass holder = new AirportClass(view); 
      return holder; 
     } 
    } 

    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 
     if(getItemViewType(position) == NEARBY) { 
      Log.i("ivt", String.valueOf(position)); 
      MenuHolder mHolder = (MenuHolder) holder; 
      mHolder.type.setText("Nearby"); 
      mHolder.type.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/Avenir-Medium.ttf"), Typeface.BOLD); 
     } else if(getItemViewType(position) == ALL) { 
      MenuHolder mHolder = (MenuHolder) holder; 
      mHolder.type.setText("All"); 
      mHolder.type.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/Avenir-Medium.ttf"), Typeface.BOLD); 
     } else if(getItemViewType(position) == COUNTRY) { 
      MenuHolder mHolder = (MenuHolder) holder; 
      mHolder.type.setText(countryName); 
      mHolder.type.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/Avenir-Medium.ttf"), Typeface.BOLD); 
     } else if(getItemViewType(position) == AIRPORTS) { 
      AirportClass mHolder = (AirportClass) holder; 
      Airport airport = listAirports.get(position - 1); 
      String country = airport.getIsoCountry().toLowerCase(); 
      if(country.equals("do")) { 
       country = "dom"; 
      } 
      int imgID = context.getResources().getIdentifier(country, "drawable", context.getPackageName()); 
      Glide.with(context).load(imgID).into(mHolder.image); 

      mHolder.des.setText(airport.getIdent()); 
      mHolder.name.setText(airport.getName()); 

      mHolder.des.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/Avenir-Book.ttf"), Typeface.BOLD); 
      mHolder.name.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/Avenir-Book.ttf")); 
     } 
    } 

    public int getItemViewType(int position) { 
     if((position == 0) && (nearbySize != 0) && (!countryFlag)) { 
      return NEARBY; 
     } else if((position == 0) && (nearbySize == 0) && (!countryFlag)) { 
      return ALL; 
     } else if((position == 0) && (countryFlag)) { 
      return COUNTRY; 
     } else { 
      return AIRPORTS; 
     } 
    } 

    @Override 
    public int getItemCount() { 
     if((nearbySize == 0) && (!countryFlag)) { 
     //rivedere 
      return 1 + listAirports.size(); 
     } else if((!countryFlag) && (nearbySize != 0)) { 
      return 1 + listAirports.size(); 
     } else { 
      return 1 + listAirports.size(); 
     } 
    } 

    public void filterResults(String text, int filterMode) { 
     String txt = text; 
     text = text == null ? null : text.toLowerCase().trim(); 
     if(text == null || "".equals(text)) { 
      listAirports = realm.where(Airport.class).findAll(); 
     } else { 
      if(filterMode == FILTER_MODE_A) { 
       listAirports = realm.where(Airport.class).contains("name", text, Case.INSENSITIVE).findAll(); 
       countryFlag = false; 
      } 
      if(filterMode == FILTER_MODE_B) { 
       System.out.print(text); 
       countryFlag = true; 
       Countries country = realm.where(Countries.class).equalTo("name", txt).findFirst(); 
       countryName = country.getName(); 
       listAirports = realm.where(Airport.class).equalTo("isoCountry", country.getCode(), Case.INSENSITIVE).findAll(); 
      } 
     } 
     updateData(listAirports); 
    } 


    public Filter getFilter(int filterMode) { 
     AirportFilter filter = new AirportFilter(this, filterMode); 
     return filter; 
    } 

    @Override 
    public Filter getFilter() { 
     return null; 
    } 


    private class AirportFilter 
      extends Filter { 
     private final AirportsAdapter adapter; 
     private int filterMode; 

     private AirportFilter(AirportsAdapter adapter, int filterMode) { 
      super(); 
      this.adapter = adapter; 
      this.filterMode = filterMode; 
     } 

     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 
      if(filterMode == FILTER_MODE_A) { 
       return new Filter.FilterResults(); 
      } 
      if(filterMode == FILTER_MODE_B) { 
       return new Filter.FilterResults(); 
      } 
      return new Filter.FilterResults(); 
     } 

     @Override 
     protected void publishResults(CharSequence constraint, FilterResults results) { 
      adapter.filterResults(constraint.toString(), filterMode); 
     } 
    } 

    private class AirportClass 
      extends RecyclerView.ViewHolder { 
     TextView name, des; 
     ImageView image; 

     public AirportClass(View itemView) { 
      super(itemView); 
      name = (TextView) itemView.findViewById(R.id.name); 
      des = (TextView) itemView.findViewById(R.id.item); 
      image = (ImageView) itemView.findViewById(R.id.color); 
     } 
    } 

    private class MenuHolder 
      extends RecyclerView.ViewHolder { 
     TextView type; 

     public MenuHolder(View itemView) { 
      super(itemView); 
      type = (TextView) itemView.findViewById(R.id.init); 
     } 
    } 
} 

Как я могу исправить эту проблему?

Благодаря

+0

Значит, вы говорите, что 'adapter.notifyDataSetChanged()' не вызывается? Или это называется, но данные еще не наступили? –

+0

@ YaroslavStavnichiy это называется, но данные еще не получены – ste9206

+0

Я вижу вызов 'findAllAsync()' непосредственно перед 'notifyDataSetChanged()'. Его название означает, что результат не сразу доступен. Возможно, вам нужно дождаться завершения или зарегистрировать обратный вызов? –

ответ

1

вы можете зарегистрировать функцию обратного вызова для запуска, когда ваш RealmQuery заканчивается, в этом обратном вы можете обновить адаптер в случае необходимости.

Вы используете версию Async, которая означает, что она не вернется сразу.

nearbs = realm.where(Airport.class) 
          .greaterThanOrEqualTo("latitudeDeg", (latitude - 0.5)) 
          .lessThanOrEqualTo("latitudeDeg", (latitude + 0.5)) 
          .greaterThanOrEqualTo("longitudeDeg", longitude - 0.5) 
          .lessThanOrEqualTo("longitudeDeg", longitude + 0.5) 
          .findAllAsync(); 
nearbs.addChangeListener(callback); 

private RealmChangeListener callback = new RealmChangeListener() { 
    @Override 
    public void onChange(RealmResults<Airport> results) { 
     adapter.notifyDataSetChanged(); 
    } 
}; 

См. Эту ссылку для получения дополнительной информации о запросах и обратных вызовах Realm. https://realm.io/docs/java/latest/#queries

+0

«RealmRecyclerViewAdapter» по умолчанию добавляет RealmChangeListener. Но я не уверен, действительно ли он набирает этот код в коде, Observable просто ошибается. – EpicPandaForce

+0

. О, хорошо, я до сих пор не использовал RealmRecyclerViewAdapter. – FrankR

Смежные вопросы