Android: TextView, содержащий текст более чем одной строки, не активируется / не активируется - PullRequest
0 голосов
/ 09 сентября 2018

Если в 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 голосов
/ 09 сентября 2018

Извините всех за то, что вы зря потратили ваше время и зажарили голову за проблему, которой на самом деле не было. Эти две кнопки «Отменить» и «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

Извините всех еще раз.

0 голосов
/ 09 сентября 2018

попробуйте поместить ваш текст в относительный макет и дать слушателю щелчка относительный макет

0 голосов
/ 09 сентября 2018

В вашем SendMessageHolder классе замените

messageRightBinding.messageHolder.setOnLongClickListener

с

itemView.setOnLongClickListener

Не следует устанавливать прослушиватель с длинным щелчком для дочернего представления в RecyclerView.

0 голосов
/ 09 сентября 2018

Установите android:clickable="true" и android:longClickable="true" на вашем TextView.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...