[第一次问问和第一次android编码器,所以如果我做错了,我深表歉意]
我正在尝试在回收站上更改itemview内部的值。但是,如果该itemview恰好在屏幕外,则findViewBy [layout,adapter或id]变为null。
public void setUserActive(UserListAdapter adapter, RecyclerView recyclerView, int position, View v) {recyclerView.findViewHolderForItemId(adapter.getItemId(position));
TextView txtActive = (TextView) vh.itemView.findViewById(R.id.user_isActive);
txtActive.setText("Active");
UserListAdapter.ViewHolder inactivevh = (UserListAdapter.ViewHolder) recyclerView.findViewHolderForItemId(adapter.getItemId(adapter.getActiveUserPosition()));
TextView txtInActive = (TextView) inactivevh.itemView.findViewById(R.id.user_isActive);
txtInActive.setText("");
adapter.setActiveUserPosition(position);
}
我尝试了几种不同的方法,从使用
UserListAdapter.ViewHolder vh = (UserListAdapter.ViewHolder) recyclerView.findViewHolderForLayoutPosition(position);
或者
UserListAdapter.ViewHolder inactivevh = (UserListAdapter.ViewHolder) recyclerView.findViewHolderForAdapterPosition(position)
并且当本应处于非 Activity 状态的 View 不在屏幕上时,它们都将失败。
我已将适配器设置为hasStableIDs = true
notifydatasetchanged似乎也无济于事。
最佳答案
如果某个项目在屏幕上(布局)在屏幕上,则可以使用您描述的方法方便地获取其 View 持有者。 如果某个项目未显示在屏幕上,则通过onBindViewHolder
滚动该项目后将立即对其进行更新。 如果未滚动,则不会向用户显示错误,因此尝试进行任何更新都将浪费处理能力(除了不可能实现,因为未分配 View 持有者)。
含义:以onBindViewHolder
能够提取最新数据的方式实现适配器。看起来您已经准备就绪,可以使用以下命令:
public void setUserActive(UserListAdapter adapter, RecyclerView recyclerView, int position) {
// Retrieve the old active user ID so we can mark him deactivated.
final int oldUserActivePosition = adapter.getActiveUserPosition();
// Setup the adapter with current data.
adapter.setActiveUserPosition(position);
// Do NOT use stable IDs and this method. It just doesn't work as expected.
// recyclerView.findViewHolderForItemId(adapter.getItemId(position));
// Activate new user.
UserListAdapter.ViewHolder holder = (UserListAdapter.ViewHolder) recyclerView.findViewHolderForAdapterPosition(position);
if (holder == null) {
// The item is off screen, no need to update it yet.
} else {
// Update the on screen item. The logic is already implemented in the adapter.
adapter.onBindViewHolder(holder, position);
}
// Deactivate previous user.
holder = (UserListAdapter.ViewHolder) recyclerView.findViewHolderForAdapterPosition(oldUserActivePosition);
if (holder != null) {
adapter.onBindViewHolder(holder, oldUserActivePosition);
}
}
当然,可以简化代码中的if-else块。编辑:
我刚刚意识到原始解决方案的复杂程度是不必要的。只要适配器可以响应您在
onBindViewHolder
中需要的所有事件,并且绑定(bind)实际上很容易,这就足够了:public void setActiveUserPosition(int position) {
if (mActiveUserPosition != position) {
int oldPosition = mActiveUserPosition;
mActiveUserPosition = position;
notifyItemChanged(oldPosition);
notifyItemChanged(position);
}
}
现在您只需要调用adapter.setActiveUserPosition(position);
即可,它使setUserActive
方法过时了。