Android:具有多行文本的TextView不可点击/长按可点击

时间:2018-09-09 11:23:52

标签: android textview

当包含聊天消息的TextView的一行内容超出可容纳的范围时,该文本视图将停止监听单击和长按。我试图在TextView的父项上侦听相同的事件,但它在那里也无法正常工作。 这是代码:

                    <TextView
                        android:id="@+id/message_text_view"
                        android:background="@drawable/bubble_right"
                        android:clickable="true"
                        android:focusable="true"
                        android:longClickable="true"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:fontFamily="@font/open_sans"
                        android:layout_marginStart="17dp"
                        android:layout_marginEnd="5dp"
                        android:paddingTop="8sp"
                        android:paddingBottom="8sp"
                        android:paddingStart="20sp"
                        android:paddingEnd="20sp"
                        android:text="@string/hello"
                        android:textColor="@color/white"
                        android:textSize="16sp" />

Java代码:

messageRightBinding.messageTextView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    messageRightBinding.messageTextView.setVisibility(View.VISIBLE);
                    return true;
                }
            });

完整的XML布局文件:

<?xml version="1.0" encoding="utf-8"?>
<layout
    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"
    tools:context=".ChatActivity">
    <data>
        <import type="android.view.View"/>
    </data>

    <LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
        <TextView
            android:id="@+id/conversation_time"
            android:visibility="gone"
            android:layout_margin="20sp"
            android:textSize="14sp"
            android:layout_gravity="center"
            android:gravity="center"
            android:textAlignment="center"
            android:text="2 July, 2018"
            android:textColor="@color/light_black"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <LinearLayout
            android:layout_width="match_parent"
            android:clickable="true"
            android:focusable="true"
            android:longClickable="true"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:gravity="end|center_vertical"
            android:padding="4dp">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="end|center_vertical"
                android:orientation="horizontal">
                <RelativeLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:clickable="true"
                    android:focusable="true"
                    android:longClickable="true"
                    android:id="@+id/message_holder">
                    <TextView
                        android:id="@+id/message_text_view"
                        android:background="@drawable/bubble_right"
                        android:clickable="false"
                        android:focusable="false"
                        android:longClickable="false"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:fontFamily="@font/open_sans"
                        android:layout_marginStart="17dp"
                        android:layout_marginEnd="5dp"
                        android:paddingTop="8sp"
                        android:paddingBottom="8sp"
                        android:paddingStart="20sp"
                        android:paddingEnd="20sp"
                        android:text="@string/hello"
                        android:textColor="@color/white"
                        android:textSize="16sp" />
                </RelativeLayout>
                <LinearLayout
                    android:visibility="gone"
                    android:id="@+id/message_button_holder"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">
                    <Button
                        android:background="@drawable/rounded_whitebackground"
                        android:backgroundTint="@color/dark_pink"
                        android:id="@+id/unsend_button_right"
                        android:layout_width="90sp"
                        android:layout_height="40sp"
                        android:layout_marginEnd="5sp"
                        android:textColor="@color/white"
                        android:textSize="16sp"
                        android:fontFamily="@font/open_sans"
                        android:padding="6sp"
                        android:text="@string/unsend" />
                    <Button
                        android:background="@drawable/rounded_whitebackground"
                        android:backgroundTint="@color/dark_pink"
                        android:id="@+id/unsend_button_right_hide"
                        android:layout_width="30sp"
                        android:layout_height="40sp"
                        android:textColor="@color/white"
                        android:textSize="16sp"
                        android:padding="8sp"
                        android:fontFamily="@font/open_sans"
                        android:text="@string/x" />
                </LinearLayout>
            </LinearLayout>
            <LinearLayout
                android:clickable="false"
                android:focusable="false"
                android:gravity="center_vertical|end"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <TextView
                    android:clickable="true"
                    android:longClickable="true"
                    android:focusable="true"
                    android:id="@+id/time_text_view"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:fontFamily="@font/roboto"
                    android:text="@string/_11_00pm"
                    android:textColor="@color/light_black"
                    android:textSize="12sp" />
                <ImageView
                    android:clickable="false"
                    android:focusable="false"
                    android:id="@+id/indicator_image_view"
                    android:layout_margin="2sp"
                    android:layout_width="12sp"
                    android:layout_height="12sp"
                    android:tint="@color/light_black"
                    app:srcCompat="@drawable/ic_check_black_24dp" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</layout>

完整的RecyclerView代码

package batteries;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

import com.squareup.picasso.Picasso;
import com.titanictek.titanicapp.R;
import com.titanictek.titanicapp.databinding.MessageLeftBinding;
import com.titanictek.titanicapp.databinding.MessageRightBinding;
import com.titanictek.titanicapp.db.AppDatabase;
import com.titanictek.titanicapp.db.Contacts;
import com.titanictek.titanicapp.db.DatabaseInstance;
import com.titanictek.titanicapp.db.NewMessage;
import com.titanictek.titanicapp.fragment.ChatFragment2;
import com.titanictek.titanicapp.services.WebSocketTypes;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;

public class ChatMessageRecyclerAdapter2 extends RecyclerView.Adapter{

    Context context;
    private UUID userId;

    // private String threadId;

    private Contacts contact;
    private ArrayList<NewMessage> newMessages;

    private static final int MESSAGE_SENT = 1;
    private static final int MESSAGE_RECEIVED = 2;
    final private RecyclerView recyclerView;
    final ChatFragment2.OnSeenCallback onSeen;

    public ChatMessageRecyclerAdapter2(Context context, UUID userId, String threadId, Contacts contact, RecyclerView recyclerView, ChatFragment2.OnSeenCallback onSeen) {
        this.context = context;
        this.userId = userId;
        // this.threadId = threadId;
        this.contact = contact;
        this.recyclerView = recyclerView;
        this.newMessages = new ArrayList<>();
        this.onSeen = onSeen;
    }

    public void setContact(Contacts contact) {
        this.contact = contact;
    }

    public void addMessagesFirst(List<NewMessage> messages) {
        newMessages.addAll(0, messages);
        // recyclerView.getLayoutManager().fi

        notifyDataSetChanged();

        recyclerView.scrollToPosition(messages.size()+5);
    }

    // todo: Add SCROLL logic
    public void clearMessages() {
        newMessages.clear();
        notifyDataSetChanged();
        scrollToBottom();
    }

    public void addMessagesInLast(List<NewMessage> messages) {
        newMessages.addAll(messages);
        notifyDataSetChanged();
        scrollToBottom();
    }

    public void addMessage(NewMessage message) {
        newMessages.add(message);
        notifyDataSetChanged();
        scrollToBottom();
    }

    public void onMessageSeen(ArrayList<String> messageIds) {
        int c = messageIds.size();
        for (NewMessage message: newMessages) {
            if (messageIds.contains(message.getMessageId())) {
                message.setReached(3);
                c--;
                if (c==0) break;
            }
        }

        if (c < messageIds.size()) notifyDataSetChanged();
    }

    public void onMessageSent(WebSocketTypes.ChatMessageDeliveryStatus status) {
        for (NewMessage message: newMessages) {
            if (message.getMessageId().equals(status.refId.toString())) {
                message.setReached(1);
                message.setMessageId(status.messageId.toString());
                notifyDataSetChanged();
                break;
            }
        }
    }

    public void onMessageDelivered(String messageId) {
        for (NewMessage message: newMessages) {
            if (message.getMessageId().equals(messageId)) {
                message.setReached(2);
                notifyDataSetChanged();
                break;
            }
        }
    }

    public void addMessagesInLast(NewMessage ...messages) {
        final int oldSize = newMessages.size();
        newMessages.addAll(Arrays.asList(messages));
        // notifyDataSetChanged();

        DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffUtil.Callback() {

            @Override
            public int getOldListSize() {
                return oldSize;
            }

            @Override
            public int getNewListSize() {
                return newMessages.size();
            }

            @Override
            public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
                return newItemPosition < oldSize;
            }

            @Override
            public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
                return newItemPosition < oldSize;
            }
        });
        diffResult.dispatchUpdatesTo(this);
        scrollToBottom();
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if(viewType == MESSAGE_SENT){
            return new SendMessageHolder(MessageRightBinding.inflate(
                    LayoutInflater.from(context), parent, false)
            );
        } else {
            return new ReceiveMessageHolder(MessageLeftBinding.inflate(
                    LayoutInflater.from(context), parent, false)
            );
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        NewMessage message = newMessages.get(position);
        if(message.getUserId().equals(userId.toString())){
            ((SendMessageHolder) holder).bind(message, position);
        } else {
            if (!message.isSeen()) {
                message.setReached(3);
                onSeen.run(message);
            }
            ((ReceiveMessageHolder) holder).bind(message, position);
        }
    }

    public void scrollToBottom() {
        if (getItemCount() > 0) {
            Log.w("SCROLL", "DONE");
            recyclerView.smoothScrollToPosition(getItemCount());
        }
    }


    @Override
    public int getItemViewType(int position) {
        NewMessage newMessage = newMessages.get(position);
        if (newMessage.getUserId().equals(userId.toString())) {
            return MESSAGE_SENT;
        } else {
            return MESSAGE_RECEIVED;
        }
    }

    private int getItemViewType(NewMessage newMessage) {
        //Log.w("NewMessage SentBy", newMessage.getUserId());
        //Log.w("NewMessage Received By", contacts.getId());
        if (newMessage.getUserId().equals(userId.toString())) {
            return MESSAGE_SENT;
        } else {
            return MESSAGE_RECEIVED;
        }
    }

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

    private class SendMessageHolder extends RecyclerView.ViewHolder{

        private MessageRightBinding messageRightBinding;

        SendMessageHolder(MessageRightBinding binding) {
            super(binding.getRoot());
            this.messageRightBinding = binding;
        }

        public void bind(NewMessage newMessage, int position){
//            messageRightBinding.mes.setText(newMessage.getText());
            messageRightBinding.messageTextView.setText(newMessage.getText());
            /*Picasso.rest().load(contacts.getProfilePicture()).resize(50, 50).
                    into(messageRightBinding.messageRightPp);*/
            if (newMessage.isSeen()) {
                messageRightBinding.indicatorImageView.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_eye_black_24dp));
            } else {
                if (newMessage.isSent())
                    messageRightBinding.indicatorImageView.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_check_black_24dp));
                else //  if (newMessage.isSentFailed())
                    messageRightBinding.indicatorImageView.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_access_time_black_24dp));
            }
            messageRightBinding.timeTextView.setText(ContentUtils.getTime(newMessage.getTime()));

            long lastTime = 0;
            messageRightBinding.conversationTime.setVisibility(View.GONE);
            if (position != 0) {
                lastTime = ChatMessageRecyclerAdapter2.this.newMessages.get(position - 1).getTime();
                if (newMessage.getTime() - lastTime >= 20000000) {
                    messageRightBinding.conversationTime.setText(new Date(newMessage.getTime()).toString());
                    messageRightBinding.conversationTime.setVisibility(View.VISIBLE);
                }
            } else {
                messageRightBinding.conversationTime.setText(new Date(newMessage.getTime()).toString());
                messageRightBinding.conversationTime.setVisibility(View.VISIBLE);
            }

            messageRightBinding.messageButtonHolder.setVisibility(View.GONE);
            messageRightBinding.messageHolder.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    messageRightBinding.messageButtonHolder.setVisibility(View.VISIBLE);
                    return true;
                }
            });

            messageRightBinding.unsendButtonRight.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    messageRightBinding.unsendButtonRight.removeCallbacks(null);
                    // newMessages.remove(position);
                    newMessages.remove(position);
                    notifyDataSetChanged(); // position -1, newMessages.size() - position );
                    Toast.makeText(context, "Unsending the message", Toast.LENGTH_SHORT).show();
                }
            });

            messageRightBinding.unsendButtonRightHide.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    messageRightBinding.messageButtonHolder.setVisibility(View.GONE);
                }
            });

        }
    }

    private class ReceiveMessageHolder extends RecyclerView.ViewHolder{

        private MessageLeftBinding messageLeftBinding;

        ReceiveMessageHolder(MessageLeftBinding binding) {
            super(binding.getRoot());
            this.messageLeftBinding = binding;
        }

        public void bind(NewMessage newMessage, int position){
            messageLeftBinding.messageTextView.setText(newMessage.getText());

            if (position +1 < ChatMessageRecyclerAdapter2.this.getItemCount() && contact != null)
                if (ChatMessageRecyclerAdapter2.this.getItemViewType(position+1) != MESSAGE_RECEIVED)
                {

                    Picasso.get().load(contact.getProfilePicture()).resize(50, 50).
                            into(messageLeftBinding.messageLeftPp);
                    messageLeftBinding.messageLeftPp.setVisibility(View.VISIBLE);
                }
                else
                    messageLeftBinding.messageLeftPp.setVisibility(View.VISIBLE);
            else if(contact != null)  {
                Picasso.get().load(contact.getProfilePicture()).resize(50, 50).
                        into(messageLeftBinding.messageLeftPp);
                messageLeftBinding.messageLeftPp.setVisibility(View.VISIBLE);
            }

            long lastTime = 0;
            messageLeftBinding.conversationTime.setVisibility(View.GONE);
            if (position != 0) {
                lastTime = ChatMessageRecyclerAdapter2.this.newMessages.get(position - 1).getTime();
                if (newMessage.getTime() - lastTime >= 20000000) {
                    messageLeftBinding.conversationTime.setText(new Date(newMessage.getTime()).toString());
                    messageLeftBinding.conversationTime.setVisibility(View.VISIBLE);
                }
            } else {
                messageLeftBinding.conversationTime.setText(new Date(newMessage.getTime()).toString());
                messageLeftBinding.conversationTime.setVisibility(View.VISIBLE);
            }

            messageLeftBinding.timeTextView.setText(ContentUtils.getTime(newMessage.getTime()));
        }
    }
}

截屏: 在这里,长按“取消发送”和“ X”按钮,但这仅适用于一条班轮邮件。 enter image description here

任何帮助或建议将不胜感激,我将非常感谢。

4 个答案:

答案 0 :(得分:1)

尝试将文本放在相对布局中,并将点击侦听器设置为相对布局

答案 1 :(得分:0)

android:clickable="true"上设置android:longClickable="true"TextView

答案 2 :(得分:0)

在您的SendMessageHolder类中,替换

messageRightBinding.messageHolder.setOnLongClickListener

itemView.setOnLongClickListener

您不应在RecyclerView的子视图中设置长按侦听器。

答案 3 :(得分:0)

抱歉,每个人都在浪费您的时间并为解决实际上没有的问题而烦恼。这两个按钮“ Unsend”和“ X”不可见,因为当TextView的内容长度超过一行时,它使用的是屏幕的整个宽度,没有其他空间。因此,即使按钮的状态可见,按钮也不在视口中。导致了如此漫长的讨论和令人误解的问题标题。

最后这对我有用:

   <LinearLayout
        android:layout_width="match_parent"
        android:clickable="true"
        android:focusable="true"
        android:longClickable="true"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:gravity="end|center_vertical"
        android:padding="4dp">
   <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="end|center_vertical"
    android:orientation="horizontal"
    android:id="@+id/message_holder"
    android:clickable="true"
    android:focusable="true"
    android:longClickable="true">
    <TextView
        android:id="@+id/message_text_view"
        android:background="@drawable/bubble_right"
        android:clickable="true"
        android:focusable="true"
        android:longClickable="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="@font/open_sans"
        android:layout_marginStart="17dp"
        android:layout_marginEnd="5dp"
        android:paddingTop="8sp"
        android:paddingBottom="8sp"
        android:paddingStart="20sp"
        android:paddingEnd="20sp"
        android:text="@string/hello"
        android:textColor="@color/white"
        android:textSize="16sp"
        android:layout_toStartOf="@id/message_button_holder"/>
    <LinearLayout
        android:visibility="gone"
        android:id="@+id/message_button_holder"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:background="@drawable/rounded_whitebackground"
            android:backgroundTint="@color/dark_pink"
            android:id="@+id/unsend_button_right"
            android:layout_width="90sp"
            android:layout_height="40sp"
            android:layout_marginEnd="5sp"
            android:textColor="@color/white"
            android:textSize="16sp"
            android:fontFamily="@font/open_sans"
            android:padding="6sp"
            android:text="@string/unsend" />
        <Button
            android:background="@drawable/rounded_whitebackground"
            android:backgroundTint="@color/dark_pink"
            android:id="@+id/unsend_button_right_hide"
            android:layout_width="30sp"
            android:layout_height="40sp"
            android:textColor="@color/white"
            android:textSize="16sp"
            android:padding="8sp"
            android:fontFamily="@font/open_sans"
            android:text="@string/x" />
    </LinearLayout>
</RelativeLayout>

enter image description here

再次对大家表示抱歉。