我正在编写一个由ApiRest填充的autocompleteTextView适配器。我正在使用rxJava和Retrofit 2.但无法获得过滤结果,因为我不知道如何在异步函数中返回值。这是我的代码
public class DiagnosticoAutoCompleteAdapter extends BaseAdapter implements Filterable {
...
@Override
public Filter getFilter() {
Filter filter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
final FilterResults filterResults= new FilterResults();
if(charSequence!=null) {
ApiUtils.getAPIServiceDos()
.getDiagnosticos(charSequence.toString())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<Diagnostico>>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(List<Diagnostico> value) {
// HERE IT SHOWS ME THE SIZE E.G. 45 so The values are received correctly
System.out.println("tamaño diagnostico::"+value.size());
// HERE IT SHOWS ME THE OBJECT NAME IN POSITION 0 AND ITS OK
System.out.println("contenido diagg...."+value.get(0).getNombre());
filterResults.values=value;
filterResults.count=value.size();
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
//here i lost the information. the count is 0
System.out.println("tamaño de filtered results::"+filterResults.count);
return filterResults;
}
RxJava请求正常但无法返回值。
我的问题是如何返回过滤后的结果?
答案 0 :(得分:0)
问题在于,您正在执行异步操作,其中API期望同步操作,这意味着您正在启动异步操作,而立即返回空FilterResults
,异步操作没有&# 39; t坐下并等待结果,然后将其返回到performFiltering
方法中,因此异步操作(Observer.onNext
内部)的结果在您已经返回空{后发生变化} {1}}。
FilterResults
对象是抽象类,已经在后台线程Filter
method invoked in a worker thread上完成了实际工作的繁重工作,你应该在{i}的UI线程中处理结果{3}}方法。
此API不完全适合RxJava反应模型,您可以直接在performFiltering
调用服务器调用并返回在工作线程中调用的结果。
如果你想要RxJava,你可以通过将流转换为阻塞流并返回结果来实现:
performFiltering
编辑:为什么你不应该在 @Override
protected FilterResults performFiltering(CharSequence charSequence) {
final FilterResults filterResults = new FilterResults();
if (charSequence != null) {
List<Diagnostico> value = ApiUtils.getAPIServiceDos()
.getDiagnosticos(charSequence.toString())
.toBlocking()
.first();
System.out.println("tamaño diagnostico::" + value.size());
System.out.println("contenido diagg...." + value.get(0).getNombre());
filterResults.values = value;
filterResults.count = value.size();
}
return filterResults;
}
处激活异步请求:
在publishResults
执行请求将会有效,因为它是为您在获得结果后更新UI而设计的(可能会通知适配器),因此在您执行bg中的请求后,您将返回主线程并更新适配器。
但是,它会引入一些错误,因为您没有绑定到正确的过滤生命周期,这意味着进度指示会立即消失,并且在您实际在后台获取结果时不会显示,此外,更多的服务器问题,它会在多个请求被触发时导致错误,因为之前的请求可能会在稍后的请求之后到达并使用旧数据更新适配器。这就是为什么您需要遵守过滤器API并在publishResults
以阻止方式执行请求的原因。
答案 1 :(得分:0)
您只需要调用notifyDataSetChanged()。它将更新结果。不要忘记初始化值和计数。
@NonNull
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults results = new FilterResults();
if (constraint != null) {
mCompositeDisposable.add(NetworkClient.getRetrofit().create(NetworkInterface.class)
.getPredictions(MapHelper.makeAutocompleteURL((BaseActivity) context, location, constraint.toString(), Config.SEARCH_RADIUS * 1000))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()).subscribeWith(new DisposableObserver<PlaceSerializer>(){
@Override
public void onNext(PlaceSerializer placeSerializer) {
data = new ArrayList<Place>(placeSerializer.getPlaces());
results.values = data;
results.count = data.size();
notifyDataSetChanged();
}
@Override
public void onError(Throwable e) {
LogHelper.e(TAG, e.getMessage());
}
@Override
public void onComplete() {
}
}));
results.values = data;
results.count = data.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
notifyDataSetChanged();
} else notifyDataSetInvalidated();
}
};
}