mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-22 21:19:31 +01:00
Lots of progress on selecting contacts
Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
parent
df1e65e238
commit
6427e0bafd
@ -137,7 +137,7 @@ class AdvancedUserItem(
|
|||||||
) : FlexibleViewHolder(view, adapter) {
|
) : FlexibleViewHolder(view, adapter) {
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
@BindView(R.id.name_text)
|
@BindView(R.id.participantNameTextView)
|
||||||
var contactDisplayName: EmojiTextView? = null
|
var contactDisplayName: EmojiTextView? = null
|
||||||
@JvmField
|
@JvmField
|
||||||
@BindView(R.id.secondary_text)
|
@BindView(R.id.secondary_text)
|
||||||
|
@ -268,7 +268,7 @@ class UserItem(
|
|||||||
var checkedImageView: ImageView? = null
|
var checkedImageView: ImageView? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
contactDisplayName = view.findViewById(R.id.name_text)
|
contactDisplayName = view.findViewById(R.id.participantNameTextView)
|
||||||
avatarImageView = view.findViewById(R.id.avatarImageView)
|
avatarImageView = view.findViewById(R.id.avatarImageView)
|
||||||
contactMentionId = view.findViewById(R.id.secondary_text)
|
contactMentionId = view.findViewById(R.id.secondary_text)
|
||||||
voiceOrSimpleCallImageView = view.findViewById(R.id.voiceOrSimpleCallImageView)
|
voiceOrSimpleCallImageView = view.findViewById(R.id.voiceOrSimpleCallImageView)
|
||||||
|
@ -17,6 +17,9 @@ import com.otaliastudios.elements.Presenter
|
|||||||
import com.otaliastudios.elements.extensions.FooterSource
|
import com.otaliastudios.elements.extensions.FooterSource
|
||||||
import com.otaliastudios.elements.extensions.HeaderSource
|
import com.otaliastudios.elements.extensions.HeaderSource
|
||||||
import kotlinx.android.synthetic.main.rv_item_contact.view.*
|
import kotlinx.android.synthetic.main.rv_item_contact.view.*
|
||||||
|
import kotlinx.android.synthetic.main.rv_item_contact.view.avatarImageView
|
||||||
|
import kotlinx.android.synthetic.main.rv_item_contact.view.participantNameTextView
|
||||||
|
import kotlinx.android.synthetic.main.rv_item_contact_selected.view.*
|
||||||
import kotlinx.android.synthetic.main.rv_item_participant_rv_footer.view.*
|
import kotlinx.android.synthetic.main.rv_item_participant_rv_footer.view.*
|
||||||
import kotlinx.android.synthetic.main.rv_item_title_header.view.*
|
import kotlinx.android.synthetic.main.rv_item_title_header.view.*
|
||||||
import org.koin.core.KoinComponent
|
import org.koin.core.KoinComponent
|
||||||
@ -26,13 +29,16 @@ open class ContactPresenter<T : Any>(context: Context, onElementClick: ((Page, H
|
|||||||
private val globalService: GlobalService by inject()
|
private val globalService: GlobalService by inject()
|
||||||
|
|
||||||
override val elementTypes: Collection<Int>
|
override val elementTypes: Collection<Int>
|
||||||
get() = listOf(ParticipantElementType.PARTICIPANT.ordinal, ParticipantElementType.PARTICIPANT_HEADER.ordinal, ParticipantElementType.PARTICIPANT_FOOTER.ordinal)
|
get() = listOf(ParticipantElementType.PARTICIPANT.ordinal, ParticipantElementType.PARTICIPANT_SELECTED.ordinal, ParticipantElementType.PARTICIPANT_HEADER.ordinal, ParticipantElementType.PARTICIPANT_FOOTER.ordinal)
|
||||||
|
|
||||||
override fun onCreate(parent: ViewGroup, elementType: Int): Holder {
|
override fun onCreate(parent: ViewGroup, elementType: Int): Holder {
|
||||||
return when (elementType) {
|
return when (elementType) {
|
||||||
ParticipantElementType.PARTICIPANT.ordinal -> {
|
ParticipantElementType.PARTICIPANT.ordinal -> {
|
||||||
Holder(getLayoutInflater().inflate(R.layout.rv_item_contact, parent, false))
|
Holder(getLayoutInflater().inflate(R.layout.rv_item_contact, parent, false))
|
||||||
}
|
}
|
||||||
|
ParticipantElementType.PARTICIPANT_SELECTED.ordinal -> {
|
||||||
|
Holder(getLayoutInflater().inflate(R.layout.rv_item_contact_selected, parent, false))
|
||||||
|
}
|
||||||
ParticipantElementType.PARTICIPANT_HEADER.ordinal -> {
|
ParticipantElementType.PARTICIPANT_HEADER.ordinal -> {
|
||||||
Holder(getLayoutInflater().inflate(R.layout.rv_item_title_header, parent, false))
|
Holder(getLayoutInflater().inflate(R.layout.rv_item_title_header, parent, false))
|
||||||
}
|
}
|
||||||
@ -45,19 +51,26 @@ open class ContactPresenter<T : Any>(context: Context, onElementClick: ((Page, H
|
|||||||
override fun onBind(page: Page, holder: Holder, element: Element<T>, payloads: List<Any>) {
|
override fun onBind(page: Page, holder: Holder, element: Element<T>, payloads: List<Any>) {
|
||||||
super.onBind(page, holder, element, payloads)
|
super.onBind(page, holder, element, payloads)
|
||||||
|
|
||||||
if (element.type == ParticipantElementType.PARTICIPANT.ordinal) {
|
if (element.type == ParticipantElementType.PARTICIPANT.ordinal || element.type == ParticipantElementType.PARTICIPANT_SELECTED.ordinal) {
|
||||||
val participant = element.data as Participant?
|
val participant = element.data as Participant?
|
||||||
val user = globalService.currentUserLiveData.value
|
val user = globalService.currentUserLiveData.value
|
||||||
|
|
||||||
holder.itemView.checkedImageView.isVisible = participant?.selected == true
|
holder.itemView.checkedImageView?.isVisible = participant?.selected == true
|
||||||
|
|
||||||
if (!payloads.contains(ElementPayload.SELECTION_TOGGLE)) {
|
if (!payloads.contains(ElementPayload.SELECTION_TOGGLE)) {
|
||||||
participant?.displayName?.let {
|
participant?.displayName?.let {
|
||||||
holder.itemView.name_text.text = it
|
if (element.type == ParticipantElementType.PARTICIPANT_SELECTED.ordinal) {
|
||||||
|
holder.itemView.participantNameTextView.text = it.substringBefore(" ", it)
|
||||||
|
} else {
|
||||||
|
holder.itemView.participantNameTextView.text = it
|
||||||
|
|
||||||
|
}
|
||||||
} ?: run {
|
} ?: run {
|
||||||
holder.itemView.name_text.text = context.getString(R.string.nc_guest)
|
holder.itemView.participantNameTextView.text = context.getString(R.string.nc_guest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
holder.itemView.clearImageView?.load(Images().getImageWithBackground(context, R.drawable.ic_baseline_clear_24, R.color.white))
|
||||||
|
|
||||||
when (participant?.source) {
|
when (participant?.source) {
|
||||||
"users" -> {
|
"users" -> {
|
||||||
when (participant.type) {
|
when (participant.type) {
|
||||||
|
@ -2,6 +2,7 @@ package com.nextcloud.talk.newarch.features.contactsflow
|
|||||||
|
|
||||||
enum class ParticipantElementType {
|
enum class ParticipantElementType {
|
||||||
PARTICIPANT,
|
PARTICIPANT,
|
||||||
|
PARTICIPANT_SELECTED,
|
||||||
PARTICIPANT_HEADER,
|
PARTICIPANT_HEADER,
|
||||||
PARTICIPANT_FOOTER
|
PARTICIPANT_FOOTER
|
||||||
}
|
}
|
@ -5,7 +5,11 @@ import android.os.Bundle
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.observe
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.bluelinelabs.conductor.autodispose.ControllerScopeProvider
|
import com.bluelinelabs.conductor.autodispose.ControllerScopeProvider
|
||||||
import com.nextcloud.talk.R
|
import com.nextcloud.talk.R
|
||||||
import com.nextcloud.talk.models.json.participants.Participant
|
import com.nextcloud.talk.models.json.participants.Participant
|
||||||
@ -18,7 +22,8 @@ import com.otaliastudios.elements.Element
|
|||||||
import com.otaliastudios.elements.Page
|
import com.otaliastudios.elements.Page
|
||||||
import com.otaliastudios.elements.Presenter
|
import com.otaliastudios.elements.Presenter
|
||||||
import com.uber.autodispose.lifecycle.LifecycleScopeProvider
|
import com.uber.autodispose.lifecycle.LifecycleScopeProvider
|
||||||
import kotlinx.android.synthetic.main.conversations_list_view.view.*
|
import kotlinx.android.synthetic.main.contacts_list_view.view.*
|
||||||
|
import kotlinx.android.synthetic.main.conversations_list_view.view.recyclerView
|
||||||
import kotlinx.android.synthetic.main.message_state.view.*
|
import kotlinx.android.synthetic.main.message_state.view.*
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
@ -27,7 +32,8 @@ class ContactsView<T : Any>(private val bundle: Bundle? = null) : BaseView() {
|
|||||||
|
|
||||||
private lateinit var viewModel: ContactsViewModel
|
private lateinit var viewModel: ContactsViewModel
|
||||||
val factory: ContactsViewModelFactory by inject()
|
val factory: ContactsViewModelFactory by inject()
|
||||||
lateinit var adapter: Adapter
|
lateinit var participantsAdapter: Adapter
|
||||||
|
lateinit var selectedParticipantsAdapter: Adapter
|
||||||
override fun getLayoutId(): Int {
|
override fun getLayoutId(): Int {
|
||||||
return R.layout.contacts_list_view
|
return R.layout.contacts_list_view
|
||||||
}
|
}
|
||||||
@ -44,8 +50,8 @@ class ContactsView<T : Any>(private val bundle: Bundle? = null) : BaseView() {
|
|||||||
val view = super.onCreateView(inflater, container)
|
val view = super.onCreateView(inflater, container)
|
||||||
|
|
||||||
// todo - change empty state magic
|
// todo - change empty state magic
|
||||||
adapter = Adapter.builder(this)
|
participantsAdapter = Adapter.builder(this)
|
||||||
.addSource(ContactsViewSource(viewModel.contactsLiveData, ParticipantElementType.PARTICIPANT.ordinal))
|
.addSource(ContactsViewSource(data = viewModel.contactsLiveData, elementType = ParticipantElementType.PARTICIPANT.ordinal))
|
||||||
.addSource(ContactsHeaderSource(activity as Context, ParticipantElementType.PARTICIPANT_HEADER.ordinal))
|
.addSource(ContactsHeaderSource(activity as Context, ParticipantElementType.PARTICIPANT_HEADER.ordinal))
|
||||||
.addSource(ContactsFooterSource(activity as Context, ParticipantElementType.PARTICIPANT_FOOTER.ordinal))
|
.addSource(ContactsFooterSource(activity as Context, ParticipantElementType.PARTICIPANT_FOOTER.ordinal))
|
||||||
.addPresenter(ContactPresenter(activity as Context, ::onElementClick))
|
.addPresenter(ContactPresenter(activity as Context, ::onElementClick))
|
||||||
@ -58,8 +64,24 @@ class ContactsView<T : Any>(private val bundle: Bundle? = null) : BaseView() {
|
|||||||
.setAutoScrollMode(Adapter.AUTOSCROLL_POSITION_0, true)
|
.setAutoScrollMode(Adapter.AUTOSCROLL_POSITION_0, true)
|
||||||
.into(view.recyclerView)
|
.into(view.recyclerView)
|
||||||
|
|
||||||
|
selectedParticipantsAdapter = Adapter.builder(this)
|
||||||
|
.addSource(ContactsViewSource(data = viewModel.selectedParticipantsLiveData, elementType = ParticipantElementType.PARTICIPANT_SELECTED.ordinal, loadingIndicatorsEnabled = false, errorIndicatorEnabled = false, emptyIndicatorEnabled = false))
|
||||||
|
.addPresenter(ContactPresenter(activity as Context, ::onElementClick))
|
||||||
|
.setAutoScrollMode(Adapter.AUTOSCROLL_POSITION_ANY, true)
|
||||||
|
.into(view.selectedParticipantsRecyclerView)
|
||||||
|
|
||||||
view.apply {
|
view.apply {
|
||||||
recyclerView.initRecyclerView(LinearLayoutManager(activity), adapter, true)
|
recyclerView.initRecyclerView(LinearLayoutManager(activity), participantsAdapter, true)
|
||||||
|
selectedParticipantsRecyclerView.initRecyclerView(LinearLayoutManager(activity, RecyclerView.HORIZONTAL, false), selectedParticipantsAdapter, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.apply {
|
||||||
|
selectedParticipantsLiveData.observe(this@ContactsView) { participants ->
|
||||||
|
view.selectedParticipantsRecyclerView.isVisible = participants.isNotEmpty()
|
||||||
|
view.divider.isVisible = participants.isNotEmpty()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.loadContacts()
|
viewModel.loadContacts()
|
||||||
@ -71,8 +93,16 @@ class ContactsView<T : Any>(private val bundle: Bundle? = null) : BaseView() {
|
|||||||
if (element.data is Participant?) {
|
if (element.data is Participant?) {
|
||||||
val participant = element.data as Participant?
|
val participant = element.data as Participant?
|
||||||
val isElementSelected = participant?.selected == true
|
val isElementSelected = participant?.selected == true
|
||||||
participant?.selected = !isElementSelected
|
participant?.let {
|
||||||
adapter.notifyItemChanged(holder.adapterPosition, ElementPayload.SELECTION_TOGGLE)
|
if (isElementSelected) {
|
||||||
|
viewModel.unselectParticipant(it)
|
||||||
|
} else {
|
||||||
|
viewModel.selectParticipant(it)
|
||||||
|
}
|
||||||
|
it.selected = !isElementSelected
|
||||||
|
participantsAdapter.notifyItemChanged(holder.adapterPosition, ElementPayload.SELECTION_TOGGLE)
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.nextcloud.talk.newarch.features.contactsflow
|
package com.nextcloud.talk.newarch.features.contactsflow
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.nextcloud.talk.models.json.participants.Participant
|
import com.nextcloud.talk.models.json.participants.Participant
|
||||||
@ -17,7 +18,10 @@ class ContactsViewModel constructor(
|
|||||||
private val getContactsUseCase: GetContactsUseCase,
|
private val getContactsUseCase: GetContactsUseCase,
|
||||||
val globalService: GlobalService
|
val globalService: GlobalService
|
||||||
) : BaseViewModel<ConversationsListView>(application) {
|
) : BaseViewModel<ConversationsListView>(application) {
|
||||||
val contactsLiveData = MutableLiveData<List<Participant>>()
|
private val selectedParticipants = mutableListOf<Participant>()
|
||||||
|
val selectedParticipantsLiveData: MutableLiveData<List<Participant>> = MutableLiveData()
|
||||||
|
val contactsLiveData: MutableLiveData<List<Participant>> = MutableLiveData()
|
||||||
|
|
||||||
private var searchQuery: String? = null
|
private var searchQuery: String? = null
|
||||||
var conversationToken: String? = null
|
var conversationToken: String? = null
|
||||||
|
|
||||||
@ -26,6 +30,16 @@ class ContactsViewModel constructor(
|
|||||||
loadContacts()
|
loadContacts()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun selectParticipant(participant: Participant) {
|
||||||
|
selectedParticipants.add(participant)
|
||||||
|
selectedParticipantsLiveData.postValue(selectedParticipants)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unselectParticipant(participant: Participant) {
|
||||||
|
selectedParticipants.remove(participant)
|
||||||
|
selectedParticipantsLiveData.postValue(selectedParticipants)
|
||||||
|
}
|
||||||
|
|
||||||
fun loadContacts() {
|
fun loadContacts() {
|
||||||
getContactsUseCase.invoke(viewModelScope, parametersOf(globalService.currentUserLiveData.value, searchQuery, conversationToken), object :
|
getContactsUseCase.invoke(viewModelScope, parametersOf(globalService.currentUserLiveData.value, searchQuery, conversationToken), object :
|
||||||
UseCaseResponse<List<Participant>> {
|
UseCaseResponse<List<Participant>> {
|
||||||
|
@ -38,6 +38,10 @@ class ContactsViewSource<T : Participant>(private val data: LiveData<List<T>>, p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getElementType(data: T): Int {
|
||||||
|
return elementType
|
||||||
|
}
|
||||||
|
|
||||||
override fun dependsOn(source: Source<*>): Boolean {
|
override fun dependsOn(source: Source<*>): Boolean {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ open class ConversationPresenter(context: Context, onElementClick: ((Page, Holde
|
|||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
authorDisplayName = if (!TextUtils.isEmpty(conversation.lastMessage?.actorDisplayName)) {
|
authorDisplayName = if (!TextUtils.isEmpty(conversation.lastMessage?.actorDisplayName)) {
|
||||||
conversation.lastMessage?.actorDisplayName!!.substringBefore(" ")
|
conversation.lastMessage?.actorDisplayName!!.substringBefore(" ", conversation.lastMessage?.actorDisplayName!!)
|
||||||
} else if ("guests" == conversation.lastMessage!!.actorType)
|
} else if ("guests" == conversation.lastMessage!!.actorType)
|
||||||
context.getString(R.string.nc_guest)
|
context.getString(R.string.nc_guest)
|
||||||
else
|
else
|
||||||
|
@ -68,7 +68,7 @@ class Images {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getImageWithBackground(context: Context, drawableId: Int): Bitmap {
|
fun getImageWithBackground(context: Context, drawableId: Int, foregroundColorTint: Int? = null): Bitmap {
|
||||||
val layers = arrayOfNulls<Drawable>(2)
|
val layers = arrayOfNulls<Drawable>(2)
|
||||||
layers[0] = context.getDrawable(R.color.bg_message_list_incoming_bubble)
|
layers[0] = context.getDrawable(R.color.bg_message_list_incoming_bubble)
|
||||||
var scale = 0.25f
|
var scale = 0.25f
|
||||||
@ -76,8 +76,12 @@ class Images {
|
|||||||
scale = 0.5f
|
scale = 0.5f
|
||||||
}
|
}
|
||||||
layers[1] = ScaleDrawable(context.getDrawable(drawableId), Gravity.CENTER, scale, scale)
|
layers[1] = ScaleDrawable(context.getDrawable(drawableId), Gravity.CENTER, scale, scale)
|
||||||
|
if (foregroundColorTint != null) {
|
||||||
|
layers[1]?.setTint(context.resources.getColor(foregroundColorTint))
|
||||||
|
}
|
||||||
layers[0]?.level = 0
|
layers[0]?.level = 0
|
||||||
layers[1]?.level = 1
|
layers[1]?.level = 1
|
||||||
|
|
||||||
return LayerDrawable(layers).toBitmap()
|
return LayerDrawable(layers).toBitmap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,12 +2,29 @@
|
|||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:animateLayoutChanges="true">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/selectedParticipantsRecyclerView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="88dp"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:listitem="@layout/rv_item_contact_selected" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/divider"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1px"
|
||||||
|
android:layout_below="@id/selectedParticipantsRecyclerView"
|
||||||
|
android:background="?android:attr/listDivider" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/recyclerView"
|
android:id="@+id/recyclerView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:layout_below="@id/divider"
|
||||||
tools:listitem="@layout/rv_item_contact" />
|
tools:listitem="@layout/rv_item_contact" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
@ -26,20 +26,20 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/rv_item_view_height"
|
android:layout_height="@dimen/rv_item_view_height"
|
||||||
android:layout_margin="@dimen/margin_between_elements"
|
android:layout_margin="@dimen/margin_between_elements"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical"
|
||||||
|
android:layout_centerInParent="true">
|
||||||
|
|
||||||
<com.google.android.material.imageview.ShapeableImageView
|
<com.google.android.material.imageview.ShapeableImageView
|
||||||
android:id="@+id/avatarImageView"
|
android:id="@+id/avatarImageView"
|
||||||
android:layout_width="@dimen/small_item_height"
|
android:layout_width="@dimen/small_item_height"
|
||||||
android:layout_height="@dimen/small_item_height"
|
android:layout_height="@dimen/small_item_height"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_marginStart="@dimen/double_margin_between_elements"
|
android:layout_marginHorizontal="8dp"
|
||||||
android:layout_marginEnd="@dimen/margin_between_elements"
|
|
||||||
app:shapeAppearanceOverlay="@style/circleImageView"
|
app:shapeAppearanceOverlay="@style/circleImageView"
|
||||||
tools:srcCompat="@tools:sample/avatars"/>
|
tools:srcCompat="@tools:sample/avatars"/>
|
||||||
|
|
||||||
<androidx.emoji.widget.EmojiTextView
|
<androidx.emoji.widget.EmojiTextView
|
||||||
android:id="@+id/name_text"
|
android:id="@+id/participantNameTextView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
|
66
app/src/main/res/layout/rv_item_contact_selected.xml
Normal file
66
app/src/main/res/layout/rv_item_contact_selected.xml
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
~ Nextcloud Talk application
|
||||||
|
~
|
||||||
|
~ @author Mario Danic
|
||||||
|
~ @author Andy Scherzinger
|
||||||
|
~ Copyright (C) 2017 Mario Danic
|
||||||
|
~ Copyright (C) 2017 Andy Scherzinger
|
||||||
|
~
|
||||||
|
~ This program is free software: you can redistribute it and/or modify
|
||||||
|
~ it under the terms of the GNU General Public License as published by
|
||||||
|
~ the Free Software Foundation, either version 3 of the License, or
|
||||||
|
~ at your option) any later version.
|
||||||
|
~
|
||||||
|
~ This program is distributed in the hope that it will be useful,
|
||||||
|
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
~ GNU General Public License for more details.
|
||||||
|
~
|
||||||
|
~ You should have received a copy of the GNU General Public License
|
||||||
|
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<RelativeLayout 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"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:layout_marginHorizontal="8dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:id="@+id/avatarFrameLayout">
|
||||||
|
|
||||||
|
<com.google.android.material.imageview.ShapeableImageView
|
||||||
|
android:id="@+id/avatarImageView"
|
||||||
|
android:layout_width="@dimen/small_item_height"
|
||||||
|
android:layout_height="@dimen/small_item_height"
|
||||||
|
app:shapeAppearanceOverlay="@style/circleImageView"
|
||||||
|
tools:srcCompat="@tools:sample/avatars"/>
|
||||||
|
|
||||||
|
<com.google.android.material.imageview.ShapeableImageView
|
||||||
|
android:id="@+id/clearImageView"
|
||||||
|
android:layout_width="16dp"
|
||||||
|
android:layout_height="16dp"
|
||||||
|
app:shapeAppearanceOverlay="@style/circleImageView"
|
||||||
|
android:layout_gravity="bottom|end"/>
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<androidx.emoji.widget.EmojiTextView
|
||||||
|
android:id="@+id/participantNameTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_below="@id/avatarFrameLayout"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="2"
|
||||||
|
tools:text="Contact item text" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
@ -74,7 +74,7 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<androidx.emoji.widget.EmojiTextView
|
<androidx.emoji.widget.EmojiTextView
|
||||||
android:id="@+id/name_text"
|
android:id="@+id/participantNameTextView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ellipsize="middle"
|
android:ellipsize="middle"
|
||||||
|
@ -69,7 +69,7 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<androidx.emoji.widget.EmojiTextView
|
<androidx.emoji.widget.EmojiTextView
|
||||||
android:id="@+id/name_text"
|
android:id="@+id/participantNameTextView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ellipsize="middle"
|
android:ellipsize="middle"
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<androidx.emoji.widget.EmojiTextView
|
<androidx.emoji.widget.EmojiTextView
|
||||||
android:id="@+id/name_text"
|
android:id="@+id/participantNameTextView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ellipsize="middle"
|
android:ellipsize="middle"
|
||||||
|
Loading…
Reference in New Issue
Block a user