0

加载新数据时,我的回收器视图会自动滚动一点,我已经尝试了许多解决方案但没有任何帮助,分页是使用 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;
    }
}
4

0 回答 0