Skip to content

Instantly share code, notes, and snippets.

@gbzarelli
Last active April 25, 2018 18:28
Show Gist options
  • Save gbzarelli/6f4b72a274524df8382c66cf07c09c34 to your computer and use it in GitHub Desktop.
Save gbzarelli/6f4b72a274524df8382c66cf07c09c34 to your computer and use it in GitHub Desktop.
Android - How to create a chat balloon with a simple XML drawable (Android – Como criar um balão de chat com um simples drawable XML)
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/margenBalaoBottom"
android:layout_marginEnd="@dimen/margenRightChat"
android:layout_marginRight="@dimen/margenRightChat"
android:background="@drawable/drawable_balloon_left"
android:paddingBottom="@dimen/paddingBalaoEsqBottom"
android:paddingEnd="@dimen/paddingBalaoEsqRight"
android:paddingLeft="@dimen/paddingBalaoEsqLeft"
android:paddingRight="@dimen/paddingBalaoEsqRight"
android:paddingStart="@dimen/paddingBalaoEsqLeft"
android:paddingTop="@dimen/paddingBalaoEsqTop">
<TextView
android:id="@+id/operador"
style="@style/Base.TextAppearance.AppCompat.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/botaoVerdePressionado"
android:textStyle="bold" />
<TextView
android:id="@+id/mensagem"
android:autoLink="web"
android:linksClickable="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/text_size_chat"
android:textStyle="bold"
app:layout_constraintTop_toBottomOf="@+id/operador" />
<TextView
android:id="@+id/data_hora"
style="@style/Base.TextAppearance.AppCompat.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/mensagem" />
</android.support.constraint.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:layout_marginBottom="@dimen/margenBalaoBottom"
android:layout_marginLeft="@dimen/margenLeftChat"
android:layout_marginStart="@dimen/margenLeftChat">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/drawable_balloon_right"
android:orientation="vertical"
android:paddingBottom="@dimen/paddingBalaoDirBottom"
android:paddingEnd="@dimen/paddingBalaoDirRight"
android:paddingLeft="@dimen/paddingBalaoDirLeft"
android:paddingRight="@dimen/paddingBalaoDirRight"
android:paddingStart="@dimen/paddingBalaoDirLeft"
android:paddingTop="@dimen/paddingBalaoDirTop"
app:layout_constraintEnd_toEndOf="parent">
<TextView
android:id="@+id/mensagem"
android:autoLink="web"
android:linksClickable="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/white"
android:textSize="@dimen/text_size_chat"
android:textStyle="bold" />
<TextView
android:id="@+id/data_hora"
style="@style/Base.TextAppearance.AppCompat.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginTop="12dp"
android:textColor="@android:color/white"
android:textStyle="bold" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
class ChatAdapter(context: Context,
private val messages: List<ObMensage>,
private val onClick: RecyclerViewAdapter.RecyclerAdapterListener<ObMensage>?) :
RecyclerView.Adapter<ChatAdapter.Holder>() {
private val inflater: LayoutInflater = LayoutInflater.from(context)
private val textSending: String = context.getString(R.string.status_msg_sending)
private val textSent: String = context.getString(R.string.status_msg_sent)
private val textRead: String = context.getString(R.string.status_msg_read)
class Holder(itemView: View) : RecyclerView.ViewHolder(itemView) {
companion object {
const val TYPE_HOLDER_USER = 1
const val TYPE_HOLDER_SUPPORT = 2
}
internal var messageView: TextView? = null
internal var operador: TextView? = null
internal var dataView: TextView? = null
internal var adapterPosition: Int? = null
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val view =
if (Holder.TYPE_HOLDER_USER == viewType) {
inflater.inflate(R.layout.balloon_right, parent, false)
} else {
inflater.inflate(R.layout.balloon_left, parent, false)
}
val holder = Holder(view)
holder.messageView = view.findViewById(R.id.mensagem)
holder.dataView = view.findViewById(R.id.data_hora)
if (Holder.TYPE_HOLDER_SUPPORT == viewType) {
holder.operador = view.findViewById(R.id.operador)
}
view.tag = holder
view.setOnClickListener({ v1 ->
val h1 = v1.tag as Holder
onClick?.onClickItem(v1, h1.adapterPosition!!, messages[h1.adapterPosition!!])
})
return holder
}
override fun onBindViewHolder(holder: Holder, position: Int) {
val message = messages[position]
holder.messageView!!.text = message.mensagem
var txDataView: String = message.getFormattedDate()
if (ObMensage.OPERADOR_USUARIO == message.tipo_operador) {
txDataView += " - " +
if (message.id_mensagens == null)
textSending
else if (message.data_hora_leitura == null)
textSent
else textRead
}
holder.dataView!!.text = txDataView
holder.adapterPosition = position
if (ObMensage.OPERADOR_SUPORTE == message.tipo_operador && holder.operador != null) {
holder.operador!!.text = message.nome_operador
}
}
override fun getItemViewType(position: Int): Int {
return if (messages[position].tipo_operador == ObMensage.OPERADOR_SUPORTE)
Holder.TYPE_HOLDER_SUPPORT else Holder.TYPE_HOLDER_USER
}
override fun getItemCount(): Int {
return messages.size
}
}
<resources>
<dimen name="width_content_start">300dp</dimen>
<dimen name="icone_sistema">50dp</dimen>
<dimen name="margenLeftPadrao">16dp</dimen>
<dimen name="margenRightPadrao">16dp</dimen>
<dimen name="margenTopPadrao">10dp</dimen>
<dimen name="margenBottomPadrao">10dp</dimen>
<dimen name="peso_topo_preatendimento">1</dimen>
<dimen name="fab_margin">16dp</dimen>
<dimen name="paddingBalaoEsqLeft">30dp</dimen>
<dimen name="paddingBalaoEsqRight">10dp</dimen>
<dimen name="paddingBalaoEsqTop">5dp</dimen>
<dimen name="paddingBalaoEsqBottom">5dp</dimen>
<dimen name="paddingBalaoDirLeft">10dp</dimen>
<dimen name="paddingBalaoDirRight">30dp</dimen>
<dimen name="paddingBalaoDirTop">5dp</dimen>
<dimen name="paddingBalaoDirBottom">5dp</dimen>
<dimen name="margenBalaoBottom">10dp</dimen>
<dimen name="size_bt_enviar">56dp</dimen>
<dimen name="text_size_chat">16sp</dimen>
<dimen name="padding_box_sistemas">20dp</dimen>
<dimen name="margenRightChat">30dp</dimen>
<dimen name="margenLeftChat">30dp</dimen>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<rotate
android:fromDegrees="-45"
android:pivotX="0%"
android:pivotY="0%"
android:toDegrees="0" >
<shape android:shape="rectangle" >
<solid android:color="@color/colorPrimary" />
</shape>
</rotate>
</item>
<item android:left="16dp">
<shape android:shape="rectangle" >
<solid android:color="@color/colorPrimary" />
<corners android:radius="4dp" />
</shape>
</item>
</layer-list>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<rotate
android:fromDegrees="45"
android:pivotX="100%"
android:pivotY="0%"
android:toDegrees="0" >
<shape android:shape="rectangle" >
<solid android:color="@color/colorAccent" />
</shape>
</rotate>
</item>
<item android:right="16dp">
<shape android:shape="rectangle" >
<solid android:color="@color/colorAccent" />
<corners android:radius="4dp" />
</shape>
</item>
</layer-list>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment