聊天应用程序中的反向分页不起作用

时间:2019-03-15 15:23:24

标签: java android arrays sqlite android-recyclerview

我有RecyclerView可以用于聊天,并且一切正常,但是反向分页(例如从本地SQLite数据库加载聊天记录)不能像Whatsapp或Telegram App一样工作。

在第一次加载时,默认情况下,我正在从本地SQLite数据库仅加载10条消息的用户聊天记录。如果我从顶部拉,它将加载下一条(旧的)10条消息,依此类推。

我使用Firebase Realtime Database作为我们的聊天服务器,该服务器实时同步,并且当用户发送新消息时,它将获取消息并添加到SQLite Database中,然后加载到最旧的消息上,如下面的图片中所示

enter image description here enter image description here

主班

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.chat_screen_main_fragment, container, false);
    setRetainInstance(true);

        // RECYCLER VIEW
        recyclerView = v.findViewById(R.id.Chat_Screen_Message_List);
        layoutManager = new LinearLayoutManager(getActivity());
        layoutManager.scrollToPosition(message.size() - 1);
        if (adapter == null) {
            adapter = new Chat_Adapter(getActivity(), message);
        }

        layoutManager.setStackFromEnd(true);
        layoutManager.setReverseLayout(true);

        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(adapter);

        chat_database=new Chat_Database(getActivity());

        // Testing For Pagination
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL){
                    Log.d(TAG,"Hello I am scrolling screen ");
                    isScrolling = true;
                }
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                currentVisible = layoutManager.getChildCount();
                TotalItems = layoutManager.getItemCount();
                scrolledOutItems = layoutManager.findFirstVisibleItemPosition();
                int check = TotalItems - currentVisible+scrolledOutItems;
                Log.d(TAG,"Current Visible = "+currentVisible+" Total = "+TotalItems+" Scrolled Out Items = "+scrolledOutItems+" Check = "+check);

                if (isScrolling && TotalItems == currentVisible + scrolledOutItems ){
                    Log.d(TAG,"Fetch Data Now "+OFFSET);
                    if (chatCount > OFFSET){
                        Log.d(TAG,"Total item count is more than database = "+chatCount +" "+OFFSET);
                        new databaseAsync().execute();
                        isScrolling = false;
                    }
                }
            }
        });
}


    //THIS METHOD WILL FETCH ALL MESSAGES FROM FIREBASE DATABASE
    private synchronized void append_chat_conversation(DataSnapshot dataSnapshot) {
        Iterator iterator = dataSnapshot.getChildren().iterator();


        while (iterator.hasNext()) {
            // NOW GET ALL DATA FROM FIREBASE DATABASE AND SAVE IT INTO STRINGS THEN CHECK EACH BY ITS MESSAGE TYPE
            Chat_Msg = (String) ((DataSnapshot) iterator.next()).getValue();
            Chat_FROM = (String) ((DataSnapshot) iterator.next()).getValue();
            Chat_TO = (String) ((DataSnapshot) iterator.next()).getValue();
            Chat_Type= (String) ((DataSnapshot) iterator.next()).getValue();





                if (Chat_Type.equals("Local_Image")) {
                    long id = chat_database.Insert_Chat(Session.getUserID(), "Image", Chat_Msg);

                    if (id==0){
                        return;

                    }
                    Chat_Wrapper image = new Chat_Wrapper(null, Chat_Msg, null, null, null, null, null, Chat_TimeStamp,id );
                    message.add(image);
                    adapter.notifyDataSetChanged();
                    recyclerView.post(new Runnable() {
                        @Override
                        public void run() {
                            recyclerView.smoothScrollToPosition(adapter.getItemCount());

                        }
                    });


                }   else if (Chat_Type.equals("Typed_Message")){
                    long id=chat_database.Insert_Chat(Session.getUserID(),"Text", Chat_Msg);

                    //Adding Chat Data Into Database
                    if (id==0){
                        return;
                    }

                    Chat_Wrapper chat_wrapper = new Chat_Wrapper(Chat_Msg, null, null, null, null, null, null, Chat_TimeStamp,id);
                    message.add(chat_wrapper);

                    adapter.notifyDataSetChanged();
                    recyclerView.post(new Runnable() {
                        @Override
                        public void run() {
                            recyclerView.smoothScrollToPosition(adapter.getItemCount());

                        }
                    });


                }

    }



//FETCHING DATA FROM LOCAL DATABASE 

    private  class databaseAsync extends AsyncTask<Void,Void,Void> {
        boolean checkDB_Exist,chatItemsCounts;
        private Parcelable recyclerViewState;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Log.d(TAG,"Chat Database Function "+OFFSET);

            if (OFFSET == 0){
                message.clear();
            }

            recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState();


            //chatCursor=chat_database.getUserChat(UserID_Intent);
            chatCount = chat_database.getUserChatCount(UserID_Intent);
            chatCursor=chat_database.getLimitUserChat(UserID_Intent,OFFSET);          
            chatCursor.moveToFirst();

        }

        @Override
        protected Void doInBackground(Void... voids) {
            if (checkDB_Exist && chatCursor.getCount()>0) {
                chatCursor.moveToFirst();
                do {
                    database_rowID = chatCursor.getInt(chatCursor.getColumnIndex("ID"));
                    database_userID = chatCursor.getString(chatCursor.getColumnIndex("USER_ID"));
                    database_ReceiverID = chatCursor.getString(chatCursor.getColumnIndex("RECEIVER_USER_ID"));
                    database_MessageType = chatCursor.getString(chatCursor.getColumnIndex("MESSAGE_TYPE"));
                    database_Message = chatCursor.getString(chatCursor.getColumnIndex("USER_MESSAGE"));
                    database_MsgFrom = chatCursor.getString(chatCursor.getColumnIndex("SENDER_NAME"));
                    database_MsgTo = chatCursor.getString(chatCursor.getColumnIndex("RECEIVER_NAME"));
                    database_TimeStamp = chatCursor.getString(chatCursor.getColumnIndex("TIME_STAMP"));


                        if (database_MessageType.equals("Image")) {
                            Log.d(TAG, "Message Type Is Image");
                            Log.d(TAG, "Row ID of Database " + database_rowID);
                            Chat_Wrapper image = new Chat_Wrapper(null, database_Message, null, null, null, null, null, database_TimeStamp, database_PhoneTo, UserImage_Intent, database_MsgFrom, null, null, database_rowID);
                            message.add(image);

                        } else if (database_MessageType.equals("Text")) {
                            Log.d(TAG, "Message Type Is Text");
                            Chat_Wrapper text = new Chat_Wrapper(database_Message, null, null, null, null, null, null, database_TimeStamp, database_PhoneTo, UserImage_Intent, database_MsgFrom, null, null, database_rowID);
                            message.add(text);
                        } 
                    }
                    }
                    while (chatCursor.moveToNext()) ;
                    chatCursor.close();
                }

            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);
            adapter.notifyDataSetChanged();
            OFFSET +=10;

        }
    }

聊天适配器

public class Chat_Adapter extends RecyclerView.Adapter<Chat_Adapter.ViewHolder> {


    Chat_Wrapper chat_wrapper;

    //ARRAYLIST OF MESSAGES OBJECT CONTAINING ALL THE MESSAGES IN THE THREAD
    List<Chat_Wrapper> arrayList_message;

    public Chat_Adapter(Context context, List<Chat_Wrapper> message) {
        this.context = context;
        this.arrayList_message = message;

    }


    @Override
    public Chat_Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View Layout;
        Log.d(TAG,"On Create View Holder Calling ");
        if (viewType==1){
            Log.d(TAG,"View Tyoe Is "+viewType);
            Layout=LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_screen_message_item,parent,false);
          //  ImagePath=Session.getUserImage();
        }
        else {
            Log.d(TAG,"View Type Is "+viewType);
            Layout=LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_screen_message_item_other,parent,false);
           // ImagePath=chat_wrapper.getImageView();
        }

        return new ViewHolder(Layout);
    }

    @Override
     public void onBindViewHolder(final Chat_Adapter.ViewHolder holder, final int position) {
        chat_wrapper=arrayList_message.get(position);

        context=holder.itemView.getContext();

        if (valueofImage){
            // Showing Sent User Image in thumbnail

            Glide.with(context).load(chat_wrapper.getImageSent()).apply(new RequestOptions()
                    .fitCenter()
                    .skipMemoryCache(true))
                    .thumbnail(0.1f)
                    .into(holder.Sent_Image);




        }

        }

        else if (valueofMessage){
            Log.d(TAG,"Value Of Message Running ImagePath "+ImagePath);
            holder.Sent_Video.setVisibility(View.GONE);
            holder.Sent_Image.setVisibility(View.GONE);
            holder.TimeStampImage.setVisibility(View.GONE);
            holder.TimeStampDoc.setVisibility(View.GONE);
            holder.TimeStampVideo.setVisibility(View.GONE);
            holder.Search_title.setVisibility(View.GONE);
            holder.Search_link.setVisibility(View.GONE);
            holder.Search_snippet.setVisibility(View.GONE);
            holder.Google_Image.setVisibility(View.GONE);

            holder.videoView.setVisibility(View.GONE);


            holder.Doc_FileName.setVisibility(View.GONE);
            holder.Doc_ImageView.setVisibility(View.GONE);
            holder.Doc_FileSize.setVisibility(View.GONE);

            holder.GeoFencing_Layout.setVisibility(View.GONE);
            holder.GeoFencing_Image.setVisibility(View.GONE);
            holder.GeoFencing_LatLng.setVisibility(View.GONE);
            holder.Message.setVisibility(View.VISIBLE);
            holder.TimeStamp.setVisibility(View.VISIBLE);
            holder.User_Image.setVisibility(View.VISIBLE);

            //CHECK SENDER IS SAME AS LOGGED IN USER
            if ((Session.getUserFname()+" "+Session.getUserLname()).equals(chat_wrapper.getSender_UserName())){
                ImagePath=Session.getUserImage();
                Log.d(TAG,"Session.getUserImage() "+Session.getUserImage());
                Log.d(TAG,"Value Of Message Running ImagePath "+ImagePath);

            }
            else {



            holder.Message.setText(chat_wrapper.getMessage());
            holder.TimeStamp.setText(chat_wrapper.getTimestamp());           


    }

    @Override
    public int getItemCount() {
        Log.d(TAG,"GET ITEM COUNT--Array Message List Size "+arrayList_message.size());
        return arrayList_message.size();
    }

}

SQLite查询

//This method will get row by limit
public Cursor getLimitUserChat(String UserID,int nextChat){
    database=this.getReadableDatabase();

    cursor = database.rawQuery( "SELECT * FROM " + TABLE_NAME + " Where "+ RECEIVER_USERID +"="+ UserID+" ORDER BY ID DESC LIMIT 10 OFFSET "+nextChat+"",null 
    return cursor;
}

1 个答案:

答案 0 :(得分:1)

使用message.add(chat_wrapper);会将添加的元素放在列表的末尾,以便在反转Recycler时将其显示在列表的末尾,请使用message.add(0,chat_wrapper);这样将在数组列表的开头。