【问题标题】:Android RecyclerView Changes text to Image when scrollAndroid RecyclerView在滚动时将文本更改为图像
【发布时间】:2022-02-07 04:01:51
【问题描述】:

谁能帮帮我???

问题陈述:我正在制作一个在 ChatActivity 中几乎准备就绪的聊天应用程序。功能是用户可以一起发送图像和文本,但在发送文本时它很好。当我发送图像时,问题就开始了。发送后,当我向上滚动到我的所有文本开始变为最近发送的图像。

ChatActivity.xml -

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/bg_light"
    tools:context=".ChatActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        android:theme="?attr/actionBarTheme">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <ImageView
                android:id="@+id/backArrow"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:srcCompat="@drawable/ic_back_arrow"
                app:tint="@color/white" />

            <de.hdodenhof.circleimageview.CircleImageView
                android:id="@+id/profile_image"
                android:layout_width="45dp"
                android:layout_height="45dp"
                android:layout_marginStart="5dp"
                android:padding="5dp"
                android:src="@drawable/avatar"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toEndOf="@+id/backArrow"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/userName"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_marginTop="3dp"
                android:layout_marginEnd="16dp"
                android:layout_marginBottom="13dp"
                android:fontFamily="@font/roboto"
                android:text=""
                android:textColor="@color/white"
                android:textSize="20sp"
                android:textStyle="bold"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/imageView7"
                app:layout_constraintStart_toEndOf="@+id/profile_image"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/lastSeen"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_marginEnd="16dp"
                android:layout_marginBottom="2dp"
                android:fontFamily="@font/roboto_light"
                android:text=""
                android:textColor="@color/white"
                android:textSize="12sp"
                android:textStyle="bold"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/imageView7"
                app:layout_constraintStart_toEndOf="@+id/profile_image"
                app:layout_constraintTop_toBottomOf="@+id/userName" />

            <androidx.constraintlayout.widget.Guideline
                android:id="@+id/guideline2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                app:layout_constraintGuide_begin="-22dp" />

            <androidx.constraintlayout.widget.Barrier
                android:id="@+id/barrier2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:barrierDirection="left"
                tools:layout_editor_absoluteX="395dp" />

            <ImageView
                android:id="@+id/imageView7"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="10dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:srcCompat="@drawable/ic_more"
                app:tint="@color/white" />

        </androidx.constraintlayout.widget.ConstraintLayout>

    </androidx.appcompat.widget.Toolbar>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/chatRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="611dp"
        android:nestedScrollingEnabled="false">

    </androidx.recyclerview.widget.RecyclerView>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/linear"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginTop="10dp"
        android:layout_marginEnd="10dp"
        android:layout_marginBottom="4dp">


        <View
            android:id="@+id/view14"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginStart="8dp"
            android:layout_marginEnd="8dp"
            android:background="@drawable/follow_active_btn"
            app:layout_constraintBottom_toBottomOf="@+id/etMessage"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/etMessage" />

        <EditText
            android:id="@+id/etMessage"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginBottom="4dp"
            android:background="@color/transparent"
            android:ems="10"
            android:hint="Message"
            android:inputType="textMultiLine"
            android:maxLines="4"
            android:minHeight="48dp"
            android:paddingStart="4dp"
            android:paddingLeft="4dp"
            android:paddingTop="8dp"
            android:paddingBottom="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/sendMessageImage"
            app:layout_constraintStart_toStartOf="parent" />

        <ImageView
            android:id="@+id/sendMessage"
            android:layout_width="36dp"
            android:layout_height="36dp"
            android:layout_marginEnd="8dp"
            android:padding="4dp"
            app:layout_constraintBottom_toBottomOf="@+id/etMessage"
            app:layout_constraintEnd_toEndOf="@+id/view14"
            app:layout_constraintTop_toTopOf="@+id/etMessage"
            app:srcCompat="@drawable/comment"
            app:tint="@color/purple_500" />

        <ImageView
            android:id="@+id/sendMessageImage"
            android:layout_width="36dp"
            android:layout_height="36dp"
            android:padding="4dp"
            app:layout_constraintBottom_toBottomOf="@+id/sendMessage"
            app:layout_constraintEnd_toStartOf="@+id/sendMessage"
            app:layout_constraintTop_toTopOf="@+id/sendMessage"
            app:srcCompat="@drawable/clip"
            app:tint="@color/black" />

    </androidx.constraintlayout.widget.ConstraintLayout>


</LinearLayout>

ChatAdapter.java -

package com.codinggeekers.lmsbeta.Adapter;

import android.content.Context;
import android.media.Image;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import com.codinggeekers.lmsbeta.Models.MessageModel;
import com.codinggeekers.lmsbeta.R;
import com.google.firebase.auth.FirebaseAuth;
import com.squareup.picasso.Picasso;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

public class ChatAdapter extends RecyclerView.Adapter {

    ArrayList<MessageModel> list;
    Context context;

    int SENDER_VIEW_TYPE = 1;
    int RECEIVER_VIEW_TYPE = 2;

    public ChatAdapter(ArrayList<MessageModel> list, Context context) {
        this.list = list;
        this.context = context;
    }

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

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if(viewType == SENDER_VIEW_TYPE) {
            View view = LayoutInflater.from(context).inflate(R.layout.sample_sender, parent, false);
            return new SenderViewHolder(view);
        }
        else {
            View view = LayoutInflater.from(context).inflate(R.layout.sample_receiver, parent, false);
            return new ReceiverViewHolder(view);
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        MessageModel message = list.get(position);

        Timestamp ts = new Timestamp(message.getTimestamp());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm a");
        String time = simpleDateFormat.format(ts.getTime());

        RequestOptions requestOptions = new RequestOptions();
        requestOptions = requestOptions.transforms(new CenterCrop(), new RoundedCorners(10));

        if(holder.getClass() == SenderViewHolder.class) {
            if (message.getMsgImg()!=null) {
                ((SenderViewHolder)holder).senderImageLayout.setVisibility(View.VISIBLE);
                ((SenderViewHolder)holder).senderTextLayout.setVisibility(View.GONE);
//                Picasso.get().load(message.getMsgImg()).placeholder(R.drawable.placeholder).into(((SenderViewHolder)holder).senderImage);
                Glide.with(((SenderViewHolder)holder).itemView.getContext()).load(message.getMsgImg()).apply(requestOptions)
                        .placeholder(R.drawable.placeholder).into(((SenderViewHolder)holder).senderImage);
            } else {
                ((SenderViewHolder)holder).senderMsg.setText(message.getMessage());
                ((SenderViewHolder)holder).senderTime.setText(time);
            }
        }
        else {
            if (message.getMsgImg()!=null) {
                ((ReceiverViewHolder)holder).receiverImageLayout.setVisibility(View.VISIBLE);
//                Picasso.get().load(message.getMsgImg()).placeholder(R.drawable.placeholder).into(((ReceiverViewHolder)holder).receiverImage);
                Glide.with(((ReceiverViewHolder)holder).itemView.getContext()).load(message.getMsgImg()).apply(requestOptions)
                        .placeholder(R.drawable.placeholder).into(((ReceiverViewHolder)holder).receiverImage);
            } else {
                ((ReceiverViewHolder)holder).receiverMsg.setText(message.getMessage());
                ((ReceiverViewHolder)holder).receiverTime.setText(time);
            }
        }
    }

    @Override
    public int getItemViewType(int position) {
        if(list.get(position).getuId().equals(FirebaseAuth.getInstance().getUid())) {
            return SENDER_VIEW_TYPE;
        }
        else {
            return RECEIVER_VIEW_TYPE;
        }
    }

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

    public class ReceiverViewHolder extends RecyclerView.ViewHolder {

        TextView receiverMsg, receiverTime;
        ImageView receiverImage;
        ConstraintLayout receiverImageLayout;

        public ReceiverViewHolder(@NonNull View itemView) {
            super(itemView);

            receiverMsg = itemView.findViewById(R.id.receiverText);
            receiverTime = itemView.findViewById(R.id.receiverTime);
            receiverImage = itemView.findViewById(R.id.receiverImage);
            receiverImageLayout = itemView.findViewById(R.id.imageConstraintLayoutReceiver);
        }
    }

    public class SenderViewHolder extends RecyclerView.ViewHolder {

        TextView senderMsg, senderTime;
        ImageView senderImage;
        ConstraintLayout senderImageLayout;
        ConstraintLayout senderTextLayout;

        public SenderViewHolder(@NonNull View itemView) {
            super(itemView);

            senderMsg = itemView.findViewById(R.id.senderText);
            senderTime = itemView.findViewById(R.id.senderTime);
            senderImage = itemView.findViewById(R.id.senderImage);
            senderImageLayout = itemView.findViewById(R.id.imageConstraintLayoutSender);
            senderTextLayout = itemView.findViewById(R.id.textConstraintLayoutSender);
        }
    }
}

ChatActivity.java -

package com.codinggeekers.lmsbeta;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;

import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;

import com.codinggeekers.lmsbeta.Adapter.ChatAdapter;
import com.codinggeekers.lmsbeta.Models.MessageModel;

import com.codinggeekers.lmsbeta.databinding.ActivityChatBinding;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import com.squareup.picasso.Picasso;

import java.util.ArrayList;
import java.util.Date;

public class ChatActivity extends AppCompatActivity {

    ActivityChatBinding binding;

    ProgressDialog dialog;

    FirebaseAuth auth;
    FirebaseDatabase database;
    FirebaseStorage storage;

    ActivityResultLauncher<String> galleryLauncher;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityChatBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        auth = FirebaseAuth.getInstance();
        database = FirebaseDatabase.getInstance();
        storage = FirebaseStorage.getInstance();

        dialog = new ProgressDialog(this);

        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.setTitle("Sending Image...");
        dialog.setMessage("Please wait...");
        dialog.setCancelable(false);
        dialog.setCanceledOnTouchOutside(false);

        // Sender and Receiver Ids
        final String senderId = auth.getUid();
        String receiveId = getIntent().getStringExtra("userId");
        String userName = getIntent().getStringExtra("userName");
        String profilePic = getIntent().getStringExtra("profilePic");


        binding.userName.setText(userName);
        Picasso.get().load(profilePic).placeholder(R.drawable.avatar).into(binding.profileImage);

        binding.backArrow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(ChatActivity.this, UsersChatActivity.class);
                startActivity(intent);
            }
        });

        final ArrayList<MessageModel> messageModels = new ArrayList<MessageModel>();

        final ChatAdapter chatAdapter = new ChatAdapter(messageModels, this);
        binding.chatRecyclerView.setAdapter(chatAdapter);

        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setStackFromEnd(true);
        binding.chatRecyclerView.setHasFixedSize(true);
        binding.chatRecyclerView.setLayoutManager(layoutManager);

        final String senderRoom = senderId + receiveId;
        final String receiverRoom = receiveId + senderId;

        database.getReference().child("Chats")
                .child(senderRoom)
                .addValueEventListener(new ValueEventListener() {
                    @SuppressLint("NotifyDataSetChanged")
                    @Override
                    public void onDataChange(@NonNull DataSnapshot snapshot) {
                        messageModels.clear();
                        for (DataSnapshot snapshot1 : snapshot.getChildren()) {
                            MessageModel model = snapshot1.getValue(MessageModel.class);
                            messageModels.add(model);
                        }
                        chatAdapter.notifyDataSetChanged();
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError error) {

                    }
                });

        binding.sendMessage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String message = binding.etMessage.getText().toString();
                if (message.matches("")) {

                } else {
                    final MessageModel model = new MessageModel(senderId, message, "text");
                    model.setTimestamp(new Date().getTime());
                    binding.etMessage.setText("");
                    database.getReference().child("Chats")
                            .child(senderRoom)
                            .push()
                            .setValue(model).addOnSuccessListener(new OnSuccessListener<Void>() {
                        @Override
                        public void onSuccess(@NonNull Void unused) {
                            database.getReference().child("Chats").child(receiverRoom).push().setValue(model).addOnSuccessListener(new OnSuccessListener<Void>() {
                                @Override
                                public void onSuccess(@NonNull Void unused) {

                                }
                            });
                        }
                    });
                }
            }
        });

        binding.sendMessageImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                galleryLauncher.launch("image/*");
            }
        });

        galleryLauncher = registerForActivityResult(new ActivityResultContracts.GetContent(), new ActivityResultCallback<Uri>() {
            @Override
            public void onActivityResult(Uri result) {
                dialog.show();
                final StorageReference reference = storage.getReference().child("chats")
                        .child(senderRoom).child(new Date().getTime() + "");
                reference.putFile(result).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                        reference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                            @Override
                            public void onSuccess(Uri uri) {
                                final MessageModel model = new MessageModel(senderId, new Date().getTime(), uri.toString(), "image");
                                database.getReference()
                                        .child("Chats")
                                        .child(senderRoom)
                                        .push()
                                        .setValue(model).addOnSuccessListener(new OnSuccessListener<Void>() {
                                    @Override
                                    public void onSuccess(Void unused) {
                                        database.getReference().child("Chats").child(receiverRoom).push().setValue(model).addOnSuccessListener(new OnSuccessListener<Void>() {
                                            @Override
                                            public void onSuccess(Void unused) {
                                                dialog.dismiss();
                                                binding.sendMessageImage.setImageURI(Uri.EMPTY);
                                                Intent intent = getIntent();
                                                finish();
                                                startActivity(intent);
                                            }
                                        });
                                    }
                                });
                            }
                        });
                    }
                });
            }
        });

        binding.userName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(ChatActivity.this, FriendsProfileActivity.class);
                intent.putExtra("userName", userName);
                intent.putExtra("userId", receiveId);
                intent.putExtra("profilePic", profilePic);
                startActivity(intent);
            }
        });

    }
}

【问题讨论】:

  • 如果您遇到问题,最好在发布问题时创建MCVE。您为此问题发布了近 600(六百)行行代码。人们需要解析和尝试在线调试的内容很多。请编辑您的问题并隔离问题,这样可以增加获得帮助的机会。
  • 好的,谢谢建议,我会的

标签: java android firebase firebase-realtime-database android-recyclerview


【解决方案1】:

ItemViewType 应该从 0 开始。

尝试将它们更改为:

    int SENDER_VIEW_TYPE = 0;
    int RECEIVER_VIEW_TYPE = 1;

【讨论】:

  • 嗨 simon5678,我试过了,它解决了我的一半问题,即滚动图像没有被重复,但一个问题继续存在,即在发送任何文本时,该文本实际上显示为图像先前发送。但是,当我按下并重新打开 ChatActivity 时,它显示的文本在滚动时不会改变
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-02
  • 2019-12-25
相关资源
最近更新 更多