加载新数据时,我的回收器视图会自动滚动一点,我已经尝试了许多解决方案但没有任何帮助,分页是使用 diffutil 设置的。设置seHasFixedSize
为 true 也不起作用视频可能会使问题变得清晰。
https://photos.app.goo.gl/SSiyxGWkeqvaHRPj6
这是我的适配器代码,它也是一个多视图适配器。
public class ChatAdapter extends PagedListAdapter<ChatMessage, RecyclerView.ViewHolder> {
private static final String TAG = "ChatAdapter";
private static final DiffUtil.ItemCallback<ChatMessage> DIFF_CALLBACK = new DiffUtil.ItemCallback<ChatMessage>() {
@Override
public boolean areItemsTheSame(@NonNull ChatMessage oldTopMoment, @NonNull ChatMessage newTopMoment) {
// User properties may have changed if reloaded from the DB, but ID is fixed
return oldTopMoment.getPk().equals(newTopMoment.getPk());
}
@Override
public boolean areContentsTheSame(@NonNull ChatMessage oldTopMoment, @NonNull ChatMessage newTopMoment) {
// NOTE: if you use equals, your object must properly override Object#equals() !!!
// Incorrectly returning false here will result in too many animations.
return oldTopMoment.equals(newTopMoment);
}
};
private ArrayList<String> sameRegionStores;
private boolean sendMessage;
private ChatCallback chatCallback;
private ErrorHandler errorHandler;
private boolean isAllStoreSelect;
private boolean isDetailsScreen;
private NetworkState networkState;
private ArrayList<Store> storesArrayList;
private User user;
ChatAdapter(boolean sendMessage, ChatCallback chatCallback, ErrorHandler errorHandler, boolean isAllStoreSelect) {
super(DIFF_CALLBACK);
this.sendMessage = sendMessage;
this.chatCallback = chatCallback;
this.errorHandler = errorHandler;
this.isAllStoreSelect = isAllStoreSelect;
}
public static View inflate(@NonNull ViewGroup container, @LayoutRes int layoutResId) {
return LayoutInflater.from(container.getContext()).inflate(layoutResId, container, false);
}
void setAllStoreSelect(boolean allStoreSelect, boolean isDetailsScreen) {
isAllStoreSelect = allStoreSelect;
this.isDetailsScreen = isDetailsScreen;
}
@Override
@NonNull
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == R.layout.chat_network_state_item) {
return new ChatNetworkStateItemViewHolder(inflate(parent, R.layout.chat_network_state_item), errorHandler, chatCallback);
} else if (viewType == ChatMessage.ChatType.dailyAchievements.ordinal() || viewType == ChatMessage.ChatType.storeAchievements.ordinal()) {
return new TeamChatAchievementDelegate().onCreateViewHolder(parent, sendMessage, chatCallback);
} else if (viewType == ChatMessage.ChatType.recognition.ordinal()) {
return new TeamChatRecognitionDelegate().onCreateViewHolder(parent, sendMessage, chatCallback);
} else if (viewType == ChatMessage.ChatType.message.ordinal()) {
return new TeamChatDirectMessageDelegate().onCreateViewHolder(parent, sendMessage, chatCallback, isDetailsScreen);
} else if (viewType == ChatMessage.ChatType.reply.ordinal()) {
return new TeamChatReplyDelegate().onCreateViewHolder(parent, chatCallback, isAllStoreSelect, isDetailsScreen);
} else {
return new TeamChatBaseDelegate().onCreateViewHolder(parent);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (getItemViewType(position) == R.layout.chat_network_state_item) {
// ((ChatNetworkStateItemViewHolder) holder).bind(networkState, getItemCount() - 1 == 0);
((ChatNetworkStateItemViewHolder) holder).bind(networkState);
} else {
ChatMessage chatMessage = getItem(position);
if (chatMessage == null) {
return;
}
if (holder instanceof TeamChatBaseDelegate.TeamChatBaseViewHolder) {
chatMessage.setShowingStoreName(isAllStoreSelect);
if (storesArrayList != null) {
chatMessage.setStoreName(getStoreName(chatMessage));
}
((TeamChatBaseDelegate.TeamChatBaseViewHolder) holder).bind(chatMessage);
}
}
}
private String getStoreName(ChatMessage chatMessage) {
String[] storeIds = chatMessage.getStoreIds();
if (storeIds == null) {
return "N/A";
}
if (user.hasPrivilege(Role.PrivilegeLevel.company)) {
for (Store store : storesArrayList) {
if (storeIds.length > 1) {
List<String> aList = Arrays.asList(storeIds);
chatMessage.setStoreListForAggregation(aList);
Timber.d("%s Restaurants", storeIds.length);
return storeIds.length + " Restaurants";
}
if (store.id.equals(storeIds[0])) {
List<String> aList = Arrays.asList(storeIds);
chatMessage.setStoreListForAggregation(aList);
Timber.d(store.name);
return store.name;
}
}
} else if (user.isDivisionManager()) {
String result = filterStoresIds(storeIds, user.store.divisionId, true);
Timber.d(result);
chatMessage.setStoreListForAggregation(sameRegionStores);
return result;
} else if (user.isMultiStoreManager()) {
String res = filterStoresIds(storeIds, user.store.regionId, false);
Timber.d(res);
chatMessage.setStoreListForAggregation(sameRegionStores);
return res;
}
return "N/A";
}
private String filterStoresIds(String[] storeIds, String id, boolean isDM) {
ArrayList<Store> storeList = getSameRegionStores(id, storeIds, isDM);
return storeList.size() == 1 ? storeList.get(0).name : storeList.size() + " Restaurants";
}
private ArrayList<Store> getSameRegionStores(String id, String[] storeIds, boolean isDM) {
ArrayList<Store> arrayList = new ArrayList<Store>();
sameRegionStores = new ArrayList<>();
for (Store store : storesArrayList) {
for (String storeId : storeIds) {
String idToCompare = "";
if (isDM) {
idToCompare = store.divisionId;
} else {
idToCompare = store.regionId;
}
if (store.id.equals(storeId) && idToCompare.equals(id)) {
sameRegionStores.add(storeId);
arrayList.add(store);
}
}
}
return arrayList;
}
@Override
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
super.onViewRecycled(holder);
if (holder instanceof TeamChatBaseDelegate.TeamChatBaseViewHolder) {
((TeamChatBaseDelegate.TeamChatBaseViewHolder) holder).unbind();
}
}
@Override
public int getItemViewType(int position) {
if (hasExtraRow() && position == getItemCount() - 1) // i.e 0
return R.layout.chat_network_state_item;
ChatMessage chatMessage = getItem(position);
if (chatMessage == null)
return -1;
return chatMessage.getType().ordinal();
}
@Override
public int getItemCount() {
return super.getItemCount() + ((hasExtraRow()) ? 1 : 0);
}
@Nullable
@Override
protected ChatMessage getItem(int position) {
// return hasExtraRow() ? super.getItem(position - 1) : super.getItem(position);
return ((position == getItemCount() - 1) && hasExtraRow()) ? null : super.getItem(position);
}
@Override
public long getItemId(int position) {
return position;
}
@MainThread
void setNetworkState(@Nullable NetworkState newNetworkState) {
if (newNetworkState == null)
return;
if (BuildConfig.DEBUG && Looper.myLooper() != Looper.getMainLooper()) {
throw new IllegalStateException("setNetworkState() called not on main thread!");
}
Timber.w("Paging adapter setNetworkState : %s", newNetworkState.getStatus().toString());
NetworkState prevNetworkState = this.networkState;
boolean hadExtraRow = hasExtraRow();
this.networkState = newNetworkState;
boolean hasExtraRow = hasExtraRow();
if (hadExtraRow != hasExtraRow) {
if (hadExtraRow) {
Timber.w("ChatAdapter notifyItemRemoved");
notifyItemRemoved(getItemCount() - 1); //(0);
} else {
Timber.w("ChatAdapter notifyItemInserted");
notifyItemInserted(getItemCount() - 1); //(0);
}
} else if (hasExtraRow && prevNetworkState != newNetworkState) {
Timber.w("ChatAdapter notifyItemChanged");
notifyItemChanged(getItemCount() - 1); //(0);
}
}
private boolean hasExtraRow() {
//TODO
// return networkState != null && (super.getItemCount() == 0 || networkState != NetworkState.LOADED);
return networkState != null && networkState != NetworkState.LOADED;
}
void setStoreList(ArrayList<Store> storesArrayList) {
this.storesArrayList = storesArrayList;
}
public void setUser(User user) {
this.user = user;
}
}