Добрый день!
Я пишу чат.
Чат как обычный recyclerview. ItemView это обычные пузыри с текстом.
Каждый пузырь должен быть размером с текст, но т.к. recyclerview переиспользует itemView большие пузыри не сдуваются до размера маленьких.
Макет с recyclerview:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/chat_window"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@id/new_message_line"
android:layout_alignParentTop="true">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/table_data"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarSize="10dp"
android:scrollbarStyle="insideInset"
android:scrollbars="vertical"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/new_message_line"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<EditText
android:id="@+id/new_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxLines="4"
android:minHeight="5dp"
android:layout_gravity="bottom"/>
<Button
android:id="@+id/send_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableBottom="@android:drawable/ic_menu_send"
android:gravity="center" />
</LinearLayout>
</RelativeLayout>
Макет сообщения
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:id="@+id/time"
android:layout_gravity="bottom"
android:gravity="left"/>
<LinearLayout
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content"
android:id="@+id/l1"
android:orientation="horizontal"
android:gravity="right">
<com.github.library.bubbleview.BubbleLinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/bubble"
android:padding="2dp"
app:arrowWidth="8dp"
app:angle="8dp"
app:arrowHeight="10dp"
app:arrowPosition="14dp"
app:arrowLocation="right"
app:arrowCenter="false"
app:bubbleColor="#0FF7EB"
>
<TextView
android:id="@+id/text_message"
android:layout_marginRight="15dp"
android:layout_marginLeft="5dp"
android:layout_marginVertical="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</com.github.library.bubbleview.BubbleLinearLayout>
</LinearLayout>
</LinearLayout>
Какие решения НЕ предлагать:
- Поместить recyclerview в NestedScrollView, т.к. recyclerview в этих условиях становится не управляем и не доступны такие функции как scrollToPosition.
- Вызов requestLayout в конце onBindViewHolder - это НЕ работает
- делать view невидимым и видимым для пересчёта - это НЕ работает
...
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setAutoMeasureEnabled(true);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
...
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
int idLayout = R.layout.my_message_view;
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(idLayout, parent, false);
MessageViewHolder messageViewHolder = new MessageViewHolder(view, mainActivity);
return messageViewHolder;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
MessageModel message = chatFragmentModel.messages.get(position);
((MessageViewHolder)holder).bind(message);
holder.itemView.requestLayout();
}
...
void bind(MessageModel messageModel){
this.messageModel = messageModel;
textView.setText(messageModel.data.get(0).messageTextEntities.get(0).textData);
}