我使用RecyclerView
来显示包含日期的项目列表,并在非UI线程上格式化我想要使用RxJava的日期。
这是我的Observable
public Observable<String> getDateFormatObservable(){
return Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
if(date == null){
if(!subscriber.isUnsubscribed()){
subscriber.onNext(dateStr);
subscriber.onCompleted();
}
return;
}
String formatedDate = "";
if(DateUtils.isToday(date)){
formatedDate = DateFormat.format("H:m", date).toString();
} else {
formatedDate = DateFormat.format("d MMM yyyy", date).toString();
}
if(!subscriber.isUnsubscribed()){
subscriber.onNext(formatedDate);
subscriber.onCompleted();
}
}
});
}
这是我订阅者的代码:
public void initDate(final TextView dateTv){
getDateFormatObservable()
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
dateTv.setText(s);
}
});
}
我从initDate
调用此onBindViewHolder
方法,并将相应的TextView
传递给它。
所以问题是 - 这样做是否安全?由于回收会有问题吗?例如,如果我快速滚动,是否有错误日期设置为TextView的情况?
P.S。当我现在测试时,似乎一切正常,但我认为当相应的TextView已经在屏幕外并且被回收并且可以设置此日期时,可能会出现调用日期OnNext
的情况。错误的TextView。但令人惊讶的是,它似乎没有发生。
答案 0 :(得分:1)
一般来说,在滚动期间准备数据是非常糟糕的主意(CursorAdapter
是另一个故事)。我想在你的情况下一切正常,因为你的代码
if(DateUtils.isToday(date)){
formatedDate = DateFormat.format("H:m", date).toString();
} else {
formatedDate = DateFormat.format("d MMM yyyy", date).toString();
}
它只是执行得非常快。不知道DateUtils.isToday
中发生了什么,但我认为你可以在UI Thread
中运行它,一切都会正常运行,你的代码会更简单。
另一个问题是,如果没有缓存,你就会不断构建formatedDate
,这只是毫无意义。
最常见的方法是按页面加载数据并将其传递给适配器。您可以创建Pojo/Model
对象并将数据存储在其中:
public class Model{
String formatedDate;
//other fields
}
您可以创建返回模型列表的方法,而不是调用getDateFormatObservable
,这些方法已经包含可见数量的列表(RecyclerView)项目的所有必要数据:
Observable<List<Model>> getModels(long fromDate, long toDate);
当用户到达列表末尾时,您需要调用该方法来加载下一页数据。