Android Реализация чата Bubble в ListView

Я нахожусь в процессе написания чата на Android, но у меня возникают проблемы с размещением чата в моем клиенте. Экран моего чата состоит из ListView с текстовым полем и кнопкой отправки внизу. Для исходящего сообщения тексты выравниваются по левому краю в строке ListView . Для входящего сообщения тексты выравниваются по правому краю в строке ListView . Тем не менее, пузырь для чата не изменяется на длину текста входящих сообщений. Эта проблема не возникает для выровненного слева исходящего сообщения.

Здесь снимок экрана ниже.

Изображение http://i40.tinypic.com/5fgen6.png

Тексты сообщений чата хранятся в базе данных и отображаются в ListView через адаптер курсора. Выравнивание текстов чата определяется на лету в исходном коде Java в MessageAdapter . Оба чата-пузыря сделаны с использованием девяти патч-образа Android.

Ниже мой макет активности чата, ListView с проблемой является messageHistoryList :

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="10dip" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ListView android:id="@+id/messageHistoryList" android:layout_width="wrap_content" android:layout_height="0px" android:layout_weight="1"/> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <EditText android:id="@+id/message" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="top" android:layout_weight="1"/> <Button android:id="@+id/sendMessageButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="4" android:text="Send"/> </LinearLayout> </LinearLayout> 

Раскладка строк ListView:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/userAndMessage"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/textUser" android:textStyle="bold" android:textColor="@color/blue"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/textMessage" android:textColor="@color/blue" android:textStyle="bold"/> </RelativeLayout> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/textTime" android:textColor="@color/blue"/> </RelativeLayout> 

Адаптер сообщений:

 public class MessageAdapter extends SimpleCursorAdapter { static final String[] FROM = { ChatHistoryManager.C_TIME }; static final int[] TO = { R.id.textTime }; static final int MESSAGE_INCOMING_DIR = 1; private String incomingMessageUserName; private String selfUserName; public MessageAdapter(Context context, Cursor cursor) { super(context, R.layout.message_list_item, cursor, FROM, TO); } @Override public void bindView(View row, Context context, Cursor cursor) { super.bindView(row, context, cursor); int messageDir = cursor.getInt(cursor.getColumnIndex(ChatHistoryManager.C_DIR)); if(messageDir == MESSAGE_INCOMING_DIR) { RelativeLayout.LayoutParams userNameAndChatMessageParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); userNameAndChatMessageParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE); RelativeLayout.LayoutParams userNameParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); userNameParams.addRule(RelativeLayout.LEFT_OF, R.id.textMessage); RelativeLayout.LayoutParams chatMessageParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); chatMessageParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, R.id.textUser); RelativeLayout.LayoutParams timeParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); timeParams.addRule(RelativeLayout.ALIGN_RIGHT, R.id.userAndMessage); timeParams.addRule(RelativeLayout.BELOW, R.id.userAndMessage); row.setBackgroundResource(R.color.grey); // Set the chat message String chatMessage = cursor.getString(cursor.getColumnIndex(ChatHistoryManager.C_TEXT)); TextView textMessage = (TextView) row.findViewById(R.id.textMessage); textMessage.setText(chatMessage.trim()); textMessage.setLayoutParams(chatMessageParams); // Format the time stamp of the message long timestamp = cursor.getLong(cursor.getColumnIndex(ChatHistoryManager.C_TIME)); TextView textTime = (TextView) row.findViewById(R.id.textTime); String readableTimeStamp = (String) DateUtils.getRelativeTimeSpanString(timestamp); textTime.setText(readableTimeStamp.trim()); textTime.setLayoutParams(timeParams); // Format the message owner and the message TextView textUser = (TextView) row.findViewById(R.id.textUser); textUser.setText(incomingMessageUserName + ": "); textUser.setLayoutParams(userNameParams); row.setBackgroundResource(R.drawable.incoming_chat_bubble); } else { RelativeLayout.LayoutParams userNameAndChatMessageParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); userNameAndChatMessageParams.addRule(RelativeLayout.RIGHT_OF, R.id.userImage); RelativeLayout.LayoutParams userImageParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); userImageParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE); RelativeLayout.LayoutParams userNameParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); userNameParams.addRule(RelativeLayout.ALIGN_LEFT, R.id.userAndMessage); RelativeLayout.LayoutParams chatMessageParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); chatMessageParams.addRule(RelativeLayout.RIGHT_OF, R.id.textUser); RelativeLayout.LayoutParams timeParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); timeParams.addRule(RelativeLayout.ALIGN_LEFT, R.id.userAndMessage); timeParams.addRule(RelativeLayout.BELOW, R.id.userAndMessage); // Set the chat message String chatMessage = cursor.getString(cursor.getColumnIndex(ChatHistoryManager.C_TEXT)); TextView textMessage = (TextView) row.findViewById(R.id.textMessage); textMessage.setText(chatMessage); textMessage.setLayoutParams(chatMessageParams); // Format the time stamp of the message long timestamp = cursor.getLong(cursor.getColumnIndex(ChatHistoryManager.C_TIME)); TextView textTime = (TextView) row.findViewById(R.id.textTime); textTime.setText(DateUtils.getRelativeTimeSpanString(timestamp)); textTime.setLayoutParams(timeParams); // Format the message owner and the message TextView textUser = (TextView) row.findViewById(R.id.textUser); textUser.setText(selfUserName + ": "); textUser.setLayoutParams(userNameParams); row.setBackgroundResource(R.drawable.outgoing_chat_bubble); } } public void setIncomingMessageUserName(String inputUserName) { this.incomingMessageUserName = inputUserName; } public void setSelfUserName(String inputUserName) { this.selfUserName = inputUserName; } } 

Используйте LinearLayout вместо Relative layout. Это решит вашу проблему. У меня была такая же проблема. Я решил это с помощью LinearLayout

Intereting Posts
Включение камеры занимает больше времени при вставке в другую нить Как сохранить соотношение сторон изображения, если изображение сначала растягивается, чтобы заполнить родительский Кнопка Android Studio Share Как создать уведомление, подобное приложению Play Music от Google Разрешение отклонено (отсутствует разрешение INTERNET?): Но предоставляется разрешение Как игнорировать элемент JSON в Android Retrofit Android – Остановить AsyncTask при нажатии кнопки «Назад» и вернуться к предыдущей операции Конверсия в формат Dalvik завершилась с ошибкой 1 – После обновления Android SDK & ADT NullPointerException: lock == null Каковы преимущества языка программирования Kotlin? Редактор в Listview android Как скрыть / показать большой палец в SeekBar Android Junit test – класс Mockito не найден исключение Безопасность с помощью SharedPreferences Исключение запущенных тестов JUnit с AndroidStudio: java.lang.NoClassDefFoundError: android / os / Parcelable