所以几周前,我问了一个问题:recyclerview periodic ui child updates。
今天,我想使用Rxjava重构该功能。它实际上非常简单,我可以通过以下方式完成:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (friend.getGameStatus().equals(GameStatus.INGAME)) {
holderOnline.startRepeatingTask();
} else {
holderOnline.stopRepeatingTask();
}
}
class MyViewHolderOnline extends RecyclerView.ViewHolder {
private Subscription subscribe;
public MyViewHolderOnline(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
public void startRepeatingTask() {
subscribe = Observable.interval(updateInterval, TimeUnit.MILLISECONDS)
.map(aLong -> current.getGameStatusToPrint())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
@Override public void onCompleted() { }
@Override public void onError(Throwable e) { }
@Override
public void onNext(String gameStatusToPrint) {
gameStatus.setText(gameStatusToPrint);
}
});
}
void stopRepeatingTask() {
if(subscribe != null && !subscribe.isUnsubscribed())
subscribe.unsubscribe();
}
}
但是问题不同。我有一个用活动实现的navigationDrawer,该活动在切换时已暂停且未销毁。因此,在我切换到不包含此适配器的活动之后,可观察对象将继续发送内容,因为它的周期间隔为可观察对象。所以我的问题是,我该怎么办?我需要在活动暂停时退订,但是我不知道该怎么办以及如何退订。有什么帮助或想法吗?
因此,如果我对您的理解正确,一种解决问题的方法是回答以下问题:在包含Activity
的RecyclerView
中,如何获得对当前显示的所有ViewHolder
的引用/ bound?
例如,要停止所有更新,您可以在onPause()
的Activity
中执行以下操作:
// assuming you are using a LinearLayoutManager:
final int firstVisibleIndex = mLinearLayoutManager.findFirstVisibleItemPosition();
final int lastVisibleIndex = mLinearLayoutManager.findLastVisibleItemPosition();
for (int i = firstVisibleIndex; i <= lastVisibleIndex; i++) {
YourViewHolder viewHolder = (YourViewHolder) findViewHolderForAdapterPosition (i);
viewHolder.stopRepeatingTask();
}
同样,您可以在onResume
的Activity
中重新启动任务。
BUT:既然我写了这篇文章,现在不确定在已绑定的ViewHolder
可见区域之外(即第一个可见项目之前或之后)是否还有RecyclerView
个但是使用这种方法无法实现。如果真是这种情况,您仍然可以遍历适配器中各项的所有索引,而只丢弃任何null
返回值。
我使用此示例
1-创建一个ViewModel
至VM_User
的名称
public class VM_User {
private String Name,Family;
public String getName() {
return Name;
}
public String getFamily() {
return Family;
}
public void setName(String name) {
Name = name;
}
public void setFamily(String family) {
Family = family;
}
}
在Adapter
上[2-为RecyclerView
创建到UserAdapter
的名称]
3-将此method
写入getData
private Single<List<VM_User>> datas() {
return Single.create(emitter -> {
Thread thread = new Thread(() -> {
try {
List<VM_User> users = new ArrayList<>();
for (int i=0;i<20;i++){
VM_User user=new VM_User();
user.setName("Diako"+i);
user.setFamily("Hasani"+i);
users.add(user);
}
emitter.onSuccess(users);
} catch (Exception e) {
emitter.onError(e);
}
});
thread.run();
});
}
4-将此method
写入以将数据设置为RecyclerView
void SetRecycler(List<VM_User> users) {
Observable<VM_User> list = Observable.fromIterable(users);
list.subscribe(vm_user -> {
//add user to `RecyclerView`
userAdapter.AddUser(vm_user);
}, throwable -> {
}, () -> {
});
}
5-用于呼叫methods
,写此method
void GetUsers() {
Single<List<VM_User>> listSingle = datas();
listSingle.subscribeWith(new DisposableSingleObserver<List<VM_User>>() {
@Override
public void onSuccess(List<VM_User> users) {
SetRecycler(users);
}
@Override
public void onError(Throwable e) {
Toast.makeText(MainActivity.this, "Error", Toast.LENGTH_SHORT).show();
}
});
}
6-将此objects
与此RecyclerView
相加
RecyclerView Recycler;
UserAdapter userAdapter;
LinearLayoutManager linearLayoutManager;
[7-在onCreate
我的Activity
中写此代码] >>
@SuppressLint("CheckResult")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Recycler = findViewById(R.id.Recycler);
linearLayoutManager = new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false);
List<VM_User> empty = new ArrayList<>();
userAdapter = new UserAdapter(empty, getApplicationContext());
Recycler.setAdapter(userAdapter);
Recycler.setLayoutManager(linearLayoutManager);
GetUsers();
}