android / codelab-android-paging

Jetpack Paging codelab
Apache License 2.0
491 stars 260 forks source link

LiveData Positions always 0 for all new items added in PagingDataAdapter #220

Closed varun7952 closed 2 years ago

varun7952 commented 2 years ago

I am using Paging 3 library with ViewMode,Room and LiveData for my chat app. My app is working fine till old text messages items loaded at first but issues start when i start sending new message (Adding new item to list). When i check positions of new items by OnClick method it always shows 0 positions for every new items added and start 1 2 3... from first old items. In my chat app every new item positions should be at 0 and other items move accordingly as all chat app work like. I am not sure where i am making mistake.

Chat Fragment For Adding Text Message.

List<ChatEntity_TableColums> message = new ArrayList<>();
ChatEntity_TableColums chatEntity_tableColums = new ChatEntity_TableColums(Chat_Msg,Chat_TimeStamp);
message.add(chatEntity_tableColums);               
ChatRoomDatabase.getInstance(MyApplication.getmContext(), 1).chatDAO().InsertChat(message);

Room Database Insert Query + Pagination Chat Query

@Insert(onConflict = OnConflictStrategy.IGNORE)
    void InsertChat(List<ChatEntity_TableColums> chat);

@Query("SELECT * FROM Chat WHERE OTHER_USER_ID = :UserID ORDER BY ID DESC")
    PagingSource<Integer, ChatEntity_TableColums>  getPaginationChat(String UserID);

ViewModel Class

public class Chat_ViewModel extends ViewModel {
    private static final String TAG = "Chat View Model";
    public final LiveData<PagingData<ChatEntity_TableColums>> chatList;

    public Chat_ViewModel() {
        Pager<Integer, ChatEntity_TableColums> pager = new Pager(
                // Create new paging config
                new PagingConfig(20, //  Count of items in one page
                        20, //  Number of items to prefetch
                        false, // Enable placeholders for data which is not yet loaded
                        20, // initialLoadSize - Count of items to be loaded initially
                        200),// maxSize - Count of total items to be shown in recyclerview
                () -> ChatRoomDatabase.getInstance(MyApplication.getmContext(), 1).chatDAO().getPaginationChat(String.valueOf(Session.getOtherUserID()))
        );

        CoroutineScope coroutineScope = ViewModelKt.getViewModelScope(this);
        chatList = PagingLiveData.cachedIn(PagingLiveData.getLiveData(pager),coroutineScope);

    }
}

Main Screen Fragment (Chat Screen)


// RECYCLER VIEW
        RecyclerView recyclerView = v.findViewById(R.id.Chat_Screen_Message_List);
        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), RecyclerView.VERTICAL, true);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setHasFixedSize(true);
        recyclerView.setAdapter(adapter);
        recyclerView.scrollToPosition(0);

viewModel = new ViewModelProvider(this).get(Chat_ViewModel.class);

        viewModel.chatList.observe(getViewLifecycleOwner(), new Observer<PagingData<ChatEntity_TableColums>>() {
            @Override
            public void onChanged(PagingData<ChatEntity_TableColums> chatEntity_tableColumsPagingData) {
                adapter.submitData(getLifecycle(), chatEntity_tableColumsPagingData);

                Log.d(TAG, "onChanged: "+chatEntity_tableColumsPagingData);
            }
        });

        adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
            @Override
            public void onItemRangeInserted(int positionStart, int itemCount) {
                super.onItemRangeInserted(positionStart, itemCount);
                Log.d(TAG, "onItemRangeInserted: " + positionStart + " " + itemCount);
                if (itemCount == 1) {
                    recyclerView.scrollToPosition(0);
                }

            }
        });

Chat Adapter (PagingDataAdapter)

 @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int pos) {
        int position = holder.getAbsoluteAdapterPosition();
        ChatEntity_TableColums wrapper = getItem(pos);
        viewHolderText.textMessage.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Log.d(TAG, "onClick: Text Position = "+position);
                    }
                });
                break;

DiffUtill.itemcallaback

private static final DiffUtil.ItemCallback<ChatEntity_TableColums> diffCallaback = new DiffUtil.ItemCallback<ChatEntity_TableColums>() {

    @Override
    public boolean areItemsTheSame(@NonNull ChatEntity_TableColums oldItem, @NonNull ChatEntity_TableColums newItem) {
        Log.d(TAG, "areItemsTheSame: Check Values 1 = " + oldItem.getDBid() + " " + newItem.getDBid());
        return oldItem.getDBid() == newItem.getDBid();
    }

    @Override
    public boolean areContentsTheSame(@NonNull ChatEntity_TableColums oldItem, @NonNull ChatEntity_TableColums newItem) {
        Log.d(TAG, "areContentsTheSame: " + oldItem.getMESSAGE_DELIVERED_STATUS() + " " + newItem.getMESSAGE_DELIVERED_STATUS());
        return oldItem.getMESSAGE_DELIVERED_STATUS() == newItem.getMESSAGE_DELIVERED_STATUS();
        //return oldItem.equals(newItem);
    }
};

If i miss anything then let me know so i can update my code. Can anyone figure out what i am doing wrong in my code which makes it

Note: I am not using adapter.notifyDataSetChanged(); anywhere, i depend on live data and viewmodel working.