Data inside RecyclerView is getting populated twice using Socket.IO

独自空忆成欢 提交于 2019-12-11 16:24:20

问题


I am working on chat application which uses Socket.IO for sending and receiving messages.Problem which i am facing is when a user send a message to other user,its message gets populated twice inside recyclerview.

My Fragment code :-

public class ChatFragment extends Fragment {


    private static final String TAG = "MainFragment";

    private static final int REQUEST_LOGIN = 0;

    private static final int TYPING_TIMER_LENGTH = 600;

    private RecyclerView mMessagesView;
    private EditText mInputMessageView;
    private ArrayList<Message> mMessages = new ArrayList<Message>();
    private RecyclerView.Adapter mAdapter;
    private boolean mTyping = false;
    private Handler mTypingHandler = new Handler();
    private String mUsername = "";
    private Socket mSocket;
    String myId ="abc";
    String friendId = "xyz";

    private Boolean isConnected = true;

    public ChatFragment() {
        super();
    }



    boolean isUser1 = false; // make false for user 2


    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mAdapter = new MessageAdapter(mMessages, context);
        if (context instanceof Activity) {

        }
    }


    public String getSendMessageString(String message) {
        try {

            JSONObject jsonObject = new JSONObject();
            if (isUser1) {////User 1
                jsonObject.put("from", myId);
                jsonObject.put("to", friendId);
            } else {
                jsonObject.put("to", friendId);
                jsonObject.put("from", myId);
            }
            jsonObject.put("room", "vamediabox");
            jsonObject.put("username", mUsername);
            jsonObject.put("messageType", "1"); //1: text message 2: multimedia message
            jsonObject.put("msg", message);
            jsonObject.put("page", 1);
            return jsonObject.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return message;
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setHasOptionsMenu(true);
        mUsername = isUser1? "Himanshu" : "Danish";
        ChatApplication app = (ChatApplication) getActivity().getApplication();
        mSocket = app.getSocket();
        mSocket.on(Socket.EVENT_CONNECT, onConnect);
        mSocket.on(Socket.EVENT_DISCONNECT, onDisconnect);
        mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectError);
        mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
        mSocket.on("new message", onNewMessage);
        mSocket.on("user joined", onUserJoined);
        mSocket.on("user left", onUserLeft);
        mSocket.on("typing", onTyping);
        mSocket.on("stop typing", onStopTyping);
        mSocket.connect();

//        startSignIn();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_chat, container, false);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        mSocket.disconnect();

        mSocket.off(Socket.EVENT_CONNECT, onConnect);
        mSocket.off(Socket.EVENT_DISCONNECT, onDisconnect);
        mSocket.off(Socket.EVENT_CONNECT_ERROR, onConnectError);
        mSocket.off(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
        mSocket.off("new message", onNewMessage);
        mSocket.off("user joined", onUserJoined);
        mSocket.off("user left", onUserLeft);
        mSocket.off("typing", onTyping);
        mSocket.off("stop typing", onStopTyping);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        mMessagesView = (RecyclerView) view.findViewById(R.id.rv_messages);
        mMessagesView.setLayoutManager(new LinearLayoutManager(getActivity()));
        mMessagesView.setAdapter(mAdapter);

        mInputMessageView = (EditText) view.findViewById(R.id.et_message);
        mInputMessageView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int id, KeyEvent event) {
                if (id == R.id.send || id == EditorInfo.IME_NULL) {
                    attemptSend();
                    return true;
                }
                return false;
            }
        });
        mInputMessageView.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (null == mUsername) return;
                if (!mSocket.connected()) return;

                if (!mTyping) {
                    mTyping = true;
                    mSocket.emit("typing", getSendMessageString(""));
                }

                mTypingHandler.removeCallbacks(onTypingTimeout);
                mTypingHandler.postDelayed(onTypingTimeout, TYPING_TIMER_LENGTH);
            }

            @Override
            public void afterTextChanged(Editable s) {
            }
        });

        Button sendButton = (Button) view.findViewById(R.id.btn_send);
        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                attemptSend();
            }
        });
    }


    private void addLog(String message) {
        mMessages.add(new Message.Builder(Message.TYPE_LOG)
                .message(message).build());
        mAdapter.notifyItemInserted(mMessages.size() - 1);
        scrollToBottom();
    }

    private void addParticipantsLog(int numUsers) {
        addLog(getResources().getQuantityString(R.plurals.message_participants, numUsers, numUsers));
    }

    private void addMessage(String username, String message , String sender) {


        if(myId == sender){


            mMessages.add(new Message.Builder(Message.SENDER)
                    .username(username).message(message).userId(sender).build());
            mAdapter.notifyItemInserted(mMessages.size() - 1);
            scrollToBottom();

        }else{


            mMessages.add(new Message.Builder(Message.RECEIVER)
                    .username(username).message(message).userId(sender).build());
            mAdapter.notifyItemInserted(mMessages.size() - 1);
            scrollToBottom();

        }


    }

    private void addTyping(String username) {
        mMessages.add(new Message.Builder(Message.TYPE_ACTION)
                .username(username).build());
        mAdapter.notifyItemInserted(mMessages.size() - 1);
        scrollToBottom();
    }

    private void removeTyping(String username) {
        for (int i = mMessages.size() - 1; i >= 0; i--) {
            Message message = mMessages.get(i);
            if (message.getType() == Message.TYPE_ACTION && message.getUsername().equals(username)) {
                mMessages.remove(i);
                mAdapter.notifyItemRemoved(i);
            }
        }
    }

    private void attemptSend() {
        if (null == mUsername) return;
        if (!mSocket.connected()) return;

        mTyping = false;

        String message = mInputMessageView.getText().toString().trim();
        if (TextUtils.isEmpty(message)) {
            mInputMessageView.requestFocus();
            return;
        }

        mInputMessageView.setText("");
        addMessage(mUsername, message,myId);

        // perform the sending message attempt.
        mSocket.emit("new message", getSendMessageString(message));
    }



    private void leave() {
        mUsername = null;
        mSocket.disconnect();
        mSocket.connect();
//        startSignIn();
    }

    private void scrollToBottom() {
        mMessagesView.scrollToPosition(mAdapter.getItemCount() - 1);
    }

    private Emitter.Listener onConnect = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (!isConnected) {
                        if (null != mUsername)
                            mSocket.emit("add user", getSendMessageString(""));
                        mSocket.emit("messages by page no", getSendMessageString(""));
                        Toast.makeText(getActivity().getApplicationContext(),
                                R.string.connect, Toast.LENGTH_LONG).show();
                        isConnected = true;
                    }
                }
            });
        }
    };

    private Emitter.Listener onDisconnect = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.i(TAG, "diconnected");
                    isConnected = false;
                    Toast.makeText(getActivity().getApplicationContext(),
                            R.string.disconnect, Toast.LENGTH_LONG).show();
                }
            });
        }
    };

    private Emitter.Listener onConnectError = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.e(TAG, "Error connecting");
                    Toast.makeText(getActivity().getApplicationContext(),
                            R.string.error_connect, Toast.LENGTH_LONG).show();
                }
            });
        }
    };

    private Emitter.Listener onNewMessage = new Emitter.Listener() {
        @Override
        public void call(final Object... args) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    JSONObject data = (JSONObject) args[0];
                    String username;
                    String message;
                    String sender;
                    try {
                        username = data.getString("username");
                        message = data.getString("message");
                        sender = data.getString("sender");

                    } catch (JSONException e) {
                        Log.e(TAG, e.getMessage());
                        return;
                    }

                    removeTyping(username);
                    if (myId == sender){



                    }else{


                        addMessage(username,message,sender);
                    }


                }
            });
        }
    };

    private Emitter.Listener onUserJoined = new Emitter.Listener() {
        @Override
        public void call(final Object... args) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    JSONObject data = (JSONObject) args[0];
                    String username;
                    int numUsers;
                    try {
                        username = data.getString("username");
                        numUsers = data.getInt("numUsers");
                    } catch (JSONException e) {
                        Log.e(TAG, e.getMessage());
                        return;
                    }

                    addLog(getResources().getString(R.string.message_user_joined, username));
                    addParticipantsLog(numUsers);
                }
            });
        }
    };

    private Emitter.Listener onUserLeft = new Emitter.Listener() {
        @Override
        public void call(final Object... args) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    JSONObject data = (JSONObject) args[0];
                    String username;
                    int numUsers;
                    try {
                        username = data.getString("username");
                        numUsers = data.getInt("numUsers");
                    } catch (JSONException e) {
                        Log.e(TAG, e.getMessage());
                        return;
                    }

                    addLog(getResources().getString(R.string.message_user_left, username));
                    addParticipantsLog(numUsers);
                    removeTyping(username);
                }
            });
        }
    };

    private Emitter.Listener onTyping = new Emitter.Listener() {
        @Override
        public void call(final Object... args) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    JSONObject data = (JSONObject) args[0];
                    String username;
                    try {
                        username = data.getString("username");
                    } catch (JSONException e) {
                        Log.e(TAG, e.getMessage());
                        return;
                    }
                    addTyping(username);
                }
            });
        }
    };

    private Emitter.Listener onStopTyping = new Emitter.Listener() {
        @Override
        public void call(final Object... args) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    JSONObject data = (JSONObject) args[0];
                    String username;
                    try {
                        username = data.getString("username");
                    } catch (JSONException e) {
                        Log.e(TAG, e.getMessage());
                        return;
                    }
                    removeTyping(username);
                }
            });
        }
    };


    private Runnable onTypingTimeout = new Runnable() {
        @Override
        public void run() {
            if (!mTyping) return;

            mTyping = false;
            mSocket.emit("stop typing", getSendMessageString(""));
        }
    };
}

My Adapter Class which i am using to inflate the layouts for the sent and received messages.

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

    ArrayList<Message> arrayList;
    Context context;
    private int SENDER = Message.SENDER;
    private int RECEIVER = Message.RECEIVER;
    private final int TYPE_LOG = Message.TYPE_LOG;
    private final int TYPE_ACTION = Message.TYPE_ACTION;



    public MessageAdapter(ArrayList<Message> arrayList, Context context) {
        this.arrayList = arrayList;
        this.context = context;


    }



    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View v = null;
        RecyclerView.ViewHolder vh = null;
        if (viewType == TYPE_LOG || viewType == TYPE_ACTION)
        {
            v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_log, parent, false);
            vh = new LogMessageHolder(v);

        }  else {

            if (viewType == SENDER) {

                v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message, parent, false);
                vh = new SenderMessageHolder(v);
            }else{

                v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message1, parent, false);
                vh = new ReceiverMessageHolder(v); }

        }

        return vh;


    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {


        Calendar currnetDateTime = Calendar.getInstance();
        SimpleDateFormat df = new SimpleDateFormat("HH:mm a");
        String currentTime = df.format(currnetDateTime.getTime());


        if (holder.getItemViewType() == TYPE_LOG || holder.getItemViewType() == TYPE_LOG) {

            ((LogMessageHolder) holder).log_msg.setText(arrayList.get(position).getMessage());
        }
        else {


            if (holder.getItemViewType() == SENDER) {
                ((SenderMessageHolder) holder).txt_send_msg.setText(arrayList.get(position).getMessage());
                ((SenderMessageHolder) holder).send_time.setText(currentTime);
            } else
            {
//                (holder.getItemViewType() == RECEIVER){
                ((ReceiverMessageHolder) holder).txt_recei_msg.setText(arrayList.get(position).getMessage());
                ((ReceiverMessageHolder) holder).recei_time.setText(currentTime);

            }
        }

    }







    @Override
    public int getItemCount() {
        return arrayList == null ? 0 : arrayList.size();
    }


    @Override
    public long getItemId(int position) {
        return position;
    }


    @Override
    public int getItemViewType(int position) {

        if(arrayList.get(position).getType() == TYPE_LOG  || arrayList.get(position).getType() == TYPE_ACTION ){

            return TYPE_LOG;
        }
        else {

            if (arrayList.get(position).getType() == SENDER){
                return SENDER;
            }
            else {

                return RECEIVER;

            }
        }


    }




    private class SenderMessageHolder extends RecyclerView.ViewHolder {
        TextView txt_send_msg, send_time;


        public SenderMessageHolder(View itemView) {
            super(itemView);
            txt_send_msg = (TextView) itemView.findViewById(R.id.txt_sender_msg);
            send_time = (TextView) itemView.findViewById(R.id.txt_sender_time);



        }
    }

    private class ReceiverMessageHolder extends RecyclerView.ViewHolder {

        TextView txt_recei_msg, recei_time;

        public ReceiverMessageHolder(View itemView) {
            super(itemView);

            txt_recei_msg = (TextView) itemView.findViewById(R.id.txt_recei_msg);
            recei_time = (TextView) itemView.findViewById(R.id.txt_recei_time);
        }
    }



    private class LogMessageHolder extends RecyclerView.ViewHolder {

        TextView log_msg;

        public LogMessageHolder(View itemView) {
            super(itemView);

            log_msg= (TextView) itemView.findViewById(R.id.message);

        }
    }

}

I am not able to figure out why the same message is getting populated for the sender that too from the left side which is actually meant for received messages only.

Here is the screenshot of the chat window.


回答1:


This code is actually fine the problem was with the hardcoded values of sender and receiver and their if and else condition .....with dynamic userid's we will not require if and else condition for the user ...it will be simple from ...sender's user id ....to receiver user id which is admin.




回答2:


just change your code like this

public String getSendMessageString(String message) {
        try {

            JSONObject jsonObject = new JSONObject();

                jsonObject.put("from", sender id);
                jsonObject.put("to", receiver id);
            jsonObject.put("room", "vamediabox");
            jsonObject.put("username", mUsername);
            jsonObject.put("messageType", "1"); //1: text message 2: multimedia message
            jsonObject.put("msg", message);
            jsonObject.put("page", 1);
            return jsonObject.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return message;
    }


来源:https://stackoverflow.com/questions/48644218/data-inside-recyclerview-is-getting-populated-twice-using-socket-io

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!