简体   繁体   English

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

[英]Android: TextView having text of more than one line is not clickable/long clickable

When TextView containing chat message is having content more than accommodatable in one line, the text view stops listening for clicks and long clicks. 当包含聊天消息的TextView的一行内容超出可容纳的范围时,该文本视图将停止监听单击和长按。 I tried to listen same events on the parent item of TextView, but it's not working there as well. 我试图在TextView的父项上侦听相同的事件,但它在那里也无法正常工作。 This is the code: 这是代码:

                    <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 code: Java代码:

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

Full XML layout file: 完整的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>

Full RecyclerView code 完整的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()));
        }
    }
}

Screenshot: Here the Unsend and X button come on long click, but that works only for one liner messages. 屏幕截图:在这里长按“取消发送”和“ X”按钮,但这仅适用于一条班轮消息。 在此处输入图片说明

Any help or suggestion will be appreciated and I will be very thankful. 任何帮助或建议将不胜感激,我将非常感谢。

尝试将文本放在相对布局中,然后将点击侦听器分配给相对布局

在您的TextView上设置android:clickable="true"android:longClickable="true"

In your SendMessageHolder class, replace 在您的SendMessageHolder类中,替换

messageRightBinding.messageHolder.setOnLongClickListener

with

itemView.setOnLongClickListener

You shouldn't set a long-click listener on a child View in a RecyclerView. 您不应在RecyclerView的子视图中设置长按侦听器。

Sorry everyone for wasting your time and frying your heads for a problem which was not there actually. 对不起,每个人都在浪费您的时间并为解决实际没有的问题而烦恼。 Those two buttons "Unsend" and "X" were not visible because when the TextView got content in length more than a line, it's was using the full width of screen leaving no space for other things. 这两个按钮“ Unsend”和“ X”不可见,因为当TextView的内容长度超过一行时,它使用的是屏幕的整个宽度,没有其他空间。 Hence even when the button's state was visible the buttons were not there in view port. 因此,即使按钮的状态可见,按钮也不在视口中。 Causing this so lengthy discussion and a misleading question title. 引起了如此冗长的讨论和令人误解的问题标题。

Finally this worked for me: 最后,这对我有用:

   <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>

在此处输入图片说明

Sorry to everyone once again. 再次对不起大家。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM