从活动更新recyclerview项目

时间:2018-12-04 11:27:48

标签: android firebase firebase-realtime-database android-recyclerview recycler-adapter

我已经构建了一个聊天应用程序,我正在添加发送到recyclerview的消息,然后再传递它。我想添加一个状态,如whatsApp(勾选发送,如果发生错误,则显示错误)。这是我的发送消息代码: 在发送消息中,我正在这样做:

public void sendMessage(final String myUId, String chatterUId, final String messageType, final String messageText) {

        if (messageText != null && !messageText.trim().equals("")) {
            //String messageType = "text"; // it is text by default
            //To update the conversation entry with latest message
            if (convId == null || convId.equals("")) {
                //generate push key as the conv Id
                convId = myConvRef.push().getKey();
            }
            final FirebaseDatabase rootDB = FirebaseDatabase.getInstance();
            final DatabaseReference messagesReference = rootDB.getReference()
                    .child(FirebaseValues.MESSAGES_TABLE)
                    .child(convId);
            sentMessagePushKey = messagesReference.push().getKey();
            sentMessage = new Message(messageText, messageType, myUId);
            messages.add(sentMessage);
            messagesKey.add(sentMessagePushKey);
            messageET.setText("");
            messagesAdapter.notifyDataSetChanged();
            messageRv.scrollToPosition(messages.size() - 1);
//Not posting full code due to stackoverflow word restriction

}

loadMessages函数是:

private void loadMessages() {
        Log.d(TAG, "Inside loadMessages()");
        messagesRef = FirebaseDatabase.getInstance().getReference().child(FirebaseValues.MESSAGES_TABLE).child(convId);
        Query messagesQuery = messagesRef.limitToLast(TOTAL_ITEM_EACH_LOAD).orderByKey();

        messagesQuery.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot ds, @Nullable String s) {
                Log.d(TAG, "Current Message Key: " + ds.getKey());
                if (itemPos++ == 0) {
                    lastKey = ds.getKey();
                }
                Log.d(TAG, "last item key is: " + lastKey);
                Message message = ds.getValue(Message.class);
                if(!sentMessagePushKey.equals(ds.getKey())){
                    messages.add(message);
                    messagesKey.add(ds.getKey());
                }
                else{
                    //The message has been updated in db successfully
                    messagesAdapter.updateSent(true);
                }
                //messages.add(message);
                /*if(topicKey!=null){
                    messagesKey.add(0,null);
                    messages.add(0,null);
                }*/
                messagesAdapter.notifyDataSetChanged();
                messageRv.scrollToPosition(messages.size() - 1);
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {

            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                messagesAdapter.updateSent(false);
            }
        });
}

添加孩子后,我想更新在recylerview项目上显示已发送的滴答声。

MessagesAdapter:

public class MessagesAdapter extends RecyclerView.Adapter<MessagesAdapter.MessageViewHolder> {
    //Other content i.e message
    private static final int CONTENT = 0;
    //Topic content
    private static final int TOPIC_TYPE = 1;
    //My message
    private static final int MY_MESSAGE = 2;
    //My Image message
    private static final int MY_IMAGE_MESSAGE = 3;
    //My Voice note
    private static final int MY_VOICE_NOTE = 4;
    //Other person's messages
    private static final int OTHER_IMAGE_MESSAGE = 5;
    private static final int OTHER_VOICE_TYPE = 6;
    private static final String TAG = "MessageAdapterTAG" ;
    static final int PERMISSION_STORAGE = 99;

    private ArrayList<Message> messages;
    private Context mContext;
    private FirebaseDatabase mDb;
    private ArrayList<String> messagesKey;
    private String topicKey;
    private String convId;
    private String myUId;
    private boolean tag = false;

    float ratingVal = -1;
    int noOfRates=0;
    public MessagesAdapter(Context context, ArrayList<Message> messages, ArrayList<String> messagesKey,String myUId, String convId, String topicKey) {
        mContext = context;
        this.messages = messages;
        mDb = FirebaseDatabase.getInstance();
        this.messagesKey = messagesKey;
        this.myUId = myUId;
        this.convId = convId;
        this.topicKey = topicKey;
    }
    View view = null;
    @Override
    public MessagesAdapter.MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if(viewType==TOPIC_TYPE){
            //User came through topic
            view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.topic_chat_layout, parent, false);
            AbsListView.LayoutParams params = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,
                    AbsListView.LayoutParams.WRAP_CONTENT);
            view.setLayoutParams(params);
        }
        else if(viewType==MY_MESSAGE){

            view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.chat_bubble_layout, parent, false);
        }
        else if(viewType==MY_IMAGE_MESSAGE){
            //Image message
            view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.my_image_message_layout, parent, false);
        }
        else if(viewType==MY_VOICE_NOTE){
            //Voice message

            view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.my_voice_message_layout, parent, false);
        }
        else if(viewType == OTHER_IMAGE_MESSAGE){
            view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.chatter_image_message_layout, parent, false);
        }
        else if(viewType==OTHER_VOICE_TYPE){
            //Voice message

            view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.chatter_voice_message_layout, parent, false);
        }
        else{
            view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.chatter_chat_bubble_layout, parent, false);
        }

        return new MessageViewHolder(view, mContext);
    }
    public void updateSent(boolean sent){
        if(sent){
            //Message is sent

        }
        else{
            //error occured
        }
    }

    @Override
    public void onBindViewHolder(@NonNull final MessageViewHolder holder, int position) {
        Message model = messages.get(position);
        if(getItemViewType(position)==TOPIC_TYPE){
            Log.d(TAG, "Topic Key:"+topicKey);
            //Log.d(TAG, "message below topic: " + model.getText());
            DatabaseReference topicRef = FirebaseDatabase.getInstance().getReference()
                    .child(FirebaseValues.TOPICS_TABLE).child(topicKey);
            topicRef.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    final Topics topic = dataSnapshot.getValue(Topics.class);
                    TextView topicTv = holder.mView.findViewById(R.id.topicTextTv);
                    TextView usernameTv = holder.mView.findViewById(R.id.usernameTv);
                    TextView timeTv = holder.mView.findViewById(R.id.timestampTv);
                    CircleImageView userImage = holder.mView.findViewById(R.id.userImg);
                    if(topic!=null){
                        final TextView rateTv;
                        rateTv = holder.mView.findViewById(R.id.ratingTv);
                        final DatabaseReference ratingRef = FirebaseDatabase.getInstance().getReference()
                                .child(FirebaseValues.RATING_TABLE)
                                .child(topic.getUid());
                        ratingRef.addValueEventListener(new ValueEventListener() {
                            @Override
                            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                                Rating rating = dataSnapshot.getValue(Rating.class);
                                if(rating!=null){
                                    ratingVal = rating.getTotal_rating();
                                    noOfRates = rating.getNo_of_rates();
                                }
                                else{
                                    ratingVal = 0;
                                }
                                rateTv.setText(String.format("%.1f", ratingVal/noOfRates)+"/5");
                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                    rateTv.setTooltipText(String.format("%.1f", ratingVal/noOfRates)+" average rating from "+ noOfRates + "ratings");
                                }
                            }

                            @Override
                            public void onCancelled(@NonNull DatabaseError databaseError) {
                                Log.e(TAG, "Database Error: "+ databaseError.getMessage());
                            }
                        });
                        TextView rateUserTv;
                        rateUserTv = holder.mView.findViewById(R.id.rateUserTv);
                        rateUserTv.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                //open rate user Dialog
                                AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(mContext);
// ...Irrelevant code for customizing the buttons and title
                                LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                                View dialogView = inflater.inflate(R.layout.rating_layout, null);
                                final SmileRating smileRating = dialogView.findViewById(R.id.smile_rating);

                                dialogBuilder.setView(dialogView);
                                final AlertDialog alertDialog = dialogBuilder.create();
                                Button submitBtn = dialogView.findViewById(R.id.submitRatingBtn);
                                submitBtn.setOnClickListener(new View.OnClickListener() {
                                    @Override
                                    public void onClick(View view) {
                                        final int rating = smileRating.getRating();
                                        if(ratingVal>=0){
                                            noOfRates+=1;
                                            float newRate = (ratingVal+rating);
                                            Log.d(TAG, "New Rating: "+newRate);
                                            Rating tempRate = new Rating(newRate, noOfRates);
                                            ratingRef.setValue(tempRate).addOnSuccessListener(new OnSuccessListener<Void>() {
                                                @Override
                                                public void onSuccess(Void aVoid) {
                                                    DatabaseReference userRatingRef = FirebaseDatabase.getInstance().getReference()
                                                            .child(FirebaseValues.USER_TABLE)
                                                            .child(topic.getUid())
                                                            .child(FirebaseValues.RATING_TABLE)
                                                            .child(myUId);
                                                    userRatingRef.setValue(rating).addOnSuccessListener(new OnSuccessListener<Void>() {
                                                        @Override
                                                        public void onSuccess(Void aVoid) {
                                                            Toast.makeText(mContext, "Thanks for rating the conversation", Toast.LENGTH_SHORT).show();
                                                            alertDialog.dismiss();
                                                        }
                                                    });
                                                }
                                            });
                                        }

                                    }
                                });
                                alertDialog.show();
                            }
                        });
                        topicTv.setText(topic.getText());
                        String time = GetTimeAgo.getTimeAgo(topic.getTimestampCreatedLong(), mContext);
                        timeTv.setText(time);
                        if(!topic.isSecret()){
                            holder.setUserImage(topic.getUid(), userImage);
                            holder.setUsername(topic.getUid(), usernameTv);
                        }
                        else{
                            usernameTv.setText("Anonymous");
                        }
                    }
                    else{
                        topicTv.setText("Topic not found");
                    }
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });
        }
        else if(getItemViewType(position)==MY_IMAGE_MESSAGE){
            holder.setImageMessage(convId,messagesKey.get(position), model.getText());
        }
        else if(getItemViewType((position))==MY_VOICE_NOTE){
            holder.setVoiceMessage(convId, messagesKey.get(position), model.getText());
        }
        else if( getItemViewType(position)==OTHER_IMAGE_MESSAGE){
            //to replace sent to received
            holder.setImageMessage(convId,messagesKey.get(position), model.getText().replace("Sent","Received"));
        }
        else if(getItemViewType(position)==OTHER_VOICE_TYPE){
            holder.setVoiceMessage(convId, messagesKey.get(position), model.getText().replace("Sent","Received"));
        }
        else{
            holder.setMessage(model.getText(), model.getFrom());
            holder.mView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    PrettyDialog pd = new PrettyDialog(mContext);
                    pd.setTitle("Message Options");
                    pd.addButton(
                            "Delete Message",     // button text
                            R.color.pdlg_color_white,  // button text color
                            R.color.pdlg_color_red,  // button background color
                            new PrettyDialogCallback() {  // button OnClick listener
                                @Override
                                public void onClick() {
                                    // Do what you gotta do
                                }
                            }
                    ).addButton(
                            "Retract Message",
                            R.color.pdlg_color_white,
                            R.color.pdlg_color_red,
                            new PrettyDialogCallback() {
                                @Override
                                public void onClick() {
                                    // Dismiss
                                }
                            }
                    ).addButton(
                            "Copy",     // button text
                            R.color.pdlg_color_white,  // button text color
                            R.color.pdlg_color_green,  // button background color
                            new PrettyDialogCallback() {  // button OnClick listener
                                @Override
                                public void onClick() {
                                    // Do what you gotta do
                                }
                            }
                    );
                    pd.show();
                    return true;
                }
            });
            Log.d(TAG, "message: " + model.getText());
        }
    }



    @Override
    public int getItemCount() {
        return messages.size();

    }


    @Override
    public int getItemViewType(int position) {
        if(position==0 && topicKey!=null){
        //Insert the topic as first element
        return TOPIC_TYPE;
    }
        Message message = messages.get(position);
        if(message.getFrom().equals(myUId)){
            //Message is mine
            if(message.getType().equals(FirebaseValues.IMAGE_TYPE)){
                return MY_IMAGE_MESSAGE;
            }
            else if(message.getType().equals(FirebaseValues.VOICE_NOTE_TYPE)){
                return MY_VOICE_NOTE;
            }
            return  MY_MESSAGE;

        }
        else{
            //The message is from other user
            if(message.getType().equals((FirebaseValues.IMAGE_TYPE))){
                return OTHER_IMAGE_MESSAGE;
            }
            else if(message.getType().equals(FirebaseValues.VOICE_NOTE_TYPE)){
                return OTHER_VOICE_TYPE;
            }
        }
        return CONTENT;
    }

由于stackoverflow的字数限制,我无法发布持有人类代码。

编辑: 我自己解决了此问题,方法是从回收者视图中删除该对象并再次添加它,然后他们在回收者视图上调用notifyItemInserted()。如果有人有更好的解决方案,请回答

0 个答案:

没有答案