Различный угловой радиус пунктов повторного просмотра - PullRequest
0 голосов
/ 25 мая 2018

Я создаю приложение для чата в Android с Kotlin.

Я использую recyclerview, и предметы имеют один из восьми фонов, в зависимости от того, являются они вашими или чужими, и являются ли они первыми/ last / middle / single во временной группе.

В recyclerview adapter есть обычный метод onBindViewHolder () для установки этих фонов.

Когда код такой:

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    val message = ...
    ...

    textTV.background = ContextCompat.getDrawable(
        context,
        when {
            msg.isLastInTimeGroup() && !msg.sentByMe -> R.drawable.chat_message_in_last_bg
            msg.isFirstInTimeGroup() && !msg.sentByMe -> R.drawable.chat_message_in_first_bg
            msg.isMiddleInTimeGroup() && !msg.sentByMe -> R.drawable.chat_message_in_middle_bg
            msg.isLastInTimeGroup() && msg.sentByMe -> R.drawable.chat_message_out_last_bg
            msg.isFirstInTimeGroup() && msg.sentByMe -> R.drawable.chat_message_out_first_bg
            msg.isMiddleInTimeGroup() && msg.sentByMe -> R.drawable.chat_message_out_middle_bg
            else -> if (msg.sentByMe) R.drawable.chat_message_out_bg else R.drawable.chat_message_in_bg
        }
    )
}

... это работает и выглядит как первая картинка ниже.Однако getDrawable () для каждого элемента неэффективно.Поэтому я извлек из функции функции рисования следующим образом:

private val inFirstBg: Drawable? = ContextCompat.getDrawable(ctx, R.drawable.chatMessageInFirstBg)
private val inMiddleBg: Drawable? = ContextCompat.getDrawable(ctx, R.drawable.chatMessageInMiddleBg)
private val inLastBg: Drawable? = ContextCompat.getDrawable(ctx, R.drawable.chatMessageInLastBg)
private val inAloneBg: Drawable? = ContextCompat.getDrawable(ctx, R.drawable.chatMessageInBg)
private val outFirstBg: Drawable? = ContextCompat.getDrawable(ctx, R.drawable.chatMessageOutFirstBg)
private val outMiddleBg: Drawable? = ContextCompat.getDrawable(ctx, R.drawable.chatMessageOutMiddleBg)
private val outLastBg: Drawable? = ContextCompat.getDrawable(ctx, R.drawable.chatMessageOutLastBg)
private val outAloneBg: Drawable? = ContextCompat.getDrawable(ctx, R.drawable.chatMessageOutBg)

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    val message = ...
    ...

    textTV.background = when {
        msg.isLastInTimeGroup() && !msg.sentByMe -> inLastBg
        msg.isFirstInTimeGroup() && !msg.sentByMe -> inFirstBg
        msg.isMiddleInTimeGroup() && !msg.sentByMe -> inMiddleBg
        msg.isLastInTimeGroup() && msg.sentByMe -> outLastBg
        msg.isFirstInTimeGroup() && msg.sentByMe -> outFirstBg
        msg.isMiddleInTimeGroup() && msg.sentByMe -> outMiddleBg
        else -> if (msg.sentByMe) outAloneBg else inAloneBg
    }
} 

... и он начинает создавать проблемы с рисованием, как на втором рисунке ниже.

Некоторые углы совсем не закруглены, фон переполняется текстом и т. Д.

Фоновые ресурсы выглядят типично (out_middle):

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/blue" />
    <corners android:radius="24dp"
        android:topRightRadius="4dp"
        android:bottomRightRadius="4dp"/>
</shape>

Почему?В чем проблема?

enter image description here enter image description here

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

Почему бы не использовать несколько типов itemView?Таким образом, drawable будет загружен один раз для ViewHolder и будет соответствующим образом использоваться при прокрутке.Для простоты вы можете использовать свой ID ресурса для рисования как itemViewType, попробуйте это:

override fun getItemViewType(position: Int): Int {
    val msg = ... // retrieve msg for [position] from dataset
    return when {
        msg.isLastInTimeGroup() && !msg.sentByMe -> R.drawable.chat_message_in_last_bg
        msg.isFirstInTimeGroup() && !msg.sentByMe -> R.drawable.chat_message_in_first_bg
        msg.isMiddleInTimeGroup() && !msg.sentByMe -> R.drawable.chat_message_in_middle_bg
        msg.isLastInTimeGroup() && msg.sentByMe -> R.drawable.chat_message_out_last_bg
        msg.isFirstInTimeGroup() && msg.sentByMe -> R.drawable.chat_message_out_first_bg
        msg.isMiddleInTimeGroup() && msg.sentByMe -> R.drawable.chat_message_out_middle_bg
        else -> if (msg.sentByMe) R.drawable.chat_message_out_bg else R.drawable.chat_message_in_bg
    }
}

Затем используйте это значение в onCreateViewHolder:

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    val holder = ... // your viewholder creation
    holder.textTV.background = ContextCompat.getDrawable(context, viewType)
}

И удалите код, изменяющий фонот onBindViewHolder полностью.

0 голосов
/ 25 мая 2018

Проблема в том, что объект рисования настраивается в соответствии с текстом, в котором он был задан первым, вы не должны устанавливать одинаковый объект рисования для каждого элемента, поскольку размер текста не фиксирован

Это не является неэффективным для полученияфон для каждого ресурса.Я уверен, что ваш первый метод не будет отставать.Чтобы проверить неэффективность, проверьте, сколько времени занимает выполнение части кода, а также проверьте память, прокрутив не менее 100 элементов и посмотрите, как она себя ведет.Дайте мне знать, если у вас возникнут какие-либо проблемы.

...