android - Realm 查询不更新我的适配器

标签 android android-recyclerview realm adapter rx-java

我需要使用 LocationManager 接收位置,在我的 Realm 数据库中搜索,最后使用 adapter.notifyDataSetChanged() 更新 RealmRecyclerViewAdapter。所以我做了这个 Observable:

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);
        }
    }
}

我该如何解决这个问题?

谢谢

最佳答案

您可以注册一个回调以在您的 RealmQuery 完成时运行,在此回调中您可以根据需要更新您的适配器。

您正在使用异步版本,这意味着它不会立即返回。

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

关于android - Realm 查询不更新我的适配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41692136/

相关文章:

android - 数据持久化安卓

java - Android 开发工具 - 错误

javascript - 在 Android 上使用 Realm 和远程调试失败

android - 在 Realm 表中选择一个随机行

ios - Realm Object 子类的实例在初始化时为 null

java - 您可以使用 Retrofit 2 和 Gson 将 ISO 8601 时间戳直接映射到 OffsetDateTime 或 ZonedDateTime 吗?

android - Gradle 无法通过 Nexus 解决依赖关系,但会在浏览器中下载 Artifact

android - 尝试在空对象上调用虚拟方法boolean RecyclerView $ ViewHolder shouldIgnore()

Android recyclerview 分隔项 4.4 兼容性

Android:调用 onLongClick() 时移动 FloatingActionButton