Added active speaker landscape layout changes

This commit is contained in:
Sylvain Berfini 2022-06-26 14:18:54 +02:00
parent e2a70c33e8
commit eb634c74e7
8 changed files with 410 additions and 227 deletions

View file

@ -1,190 +0,0 @@
/*
* Copyright (c) 2010-2021 Belledonne Communications SARL.
*
* This file is part of linphone-android
* (see https://www.linphone.org).
*
* 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/>.
*/
package org.linphone.activities.voip.views
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.view.View
import android.widget.HorizontalScrollView
import java.lang.Exception
import kotlin.math.ceil
import kotlin.math.roundToInt
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.utils.AppUtils
class HorizontalScrollDotsView : View {
private var count = 2
private var selected = 0
private var radius: Float = 5f
private var margin: Float = 2f
private var screenWidth: Float = 0f
private var itemWidth: Float = 0f
private lateinit var dotPaint: Paint
private lateinit var selectedDotPaint: Paint
private var horizontalScrollViewRef = 0
private lateinit var horizontalScrollView: HorizontalScrollView
private val scrollListener = OnScrollChangeListener { v, scrollX, _, _, _ ->
val childWidth: Int = (v as HorizontalScrollView).getChildAt(0).measuredWidth
val scrollViewWidth = v.measuredWidth
val scrollableX = childWidth - scrollViewWidth
if (scrollableX > 0) {
val percent = (scrollX.toFloat() * 100 / scrollableX).toDouble()
if (count > 1) {
val selectedDot = percent / (100 / (count - 1))
val dot = selectedDot.roundToInt()
if (dot != selected) {
setSelectedDot(dot)
}
}
}
}
constructor(context: Context) : super(context) { init(context) }
constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
init(context)
context.theme.obtainStyledAttributes(
attrs,
R.styleable.HorizontalScrollDot,
defStyleAttr, 0
).apply {
try {
radius = getDimension(R.styleable.HorizontalScrollDot_dotRadius, 5f)
count = getInt(R.styleable.HorizontalScrollDot_dotCount, 1)
val color = getColor(R.styleable.HorizontalScrollDot_dotColor, context.resources.getColor(R.color.voip_gray_dots))
dotPaint.color = color
val selectedColor = getColor(R.styleable.HorizontalScrollDot_selectedDotColor, context.resources.getColor(R.color.voip_dark_gray))
selectedDotPaint.color = selectedColor
selected = getInt(R.styleable.HorizontalScrollDot_selectedDot, 1)
horizontalScrollViewRef = getResourceId(R.styleable.HorizontalScrollDot_horizontalScrollView, 0)
Log.d("[Horizontal Scroll Dots] HorizontalScrollView reference set is $horizontalScrollViewRef")
invalidate()
} catch (e: Exception) {
Log.e("[Horizontal Scroll Dots] $e")
} finally {
recycle()
}
}
}
fun init(context: Context) {
radius = AppUtils.dpToPixels(context, 5f)
margin = AppUtils.dpToPixels(context, 5f)
dotPaint = Paint()
dotPaint.color = Color.parseColor("#D8D8D8")
selectedDotPaint = Paint()
selectedDotPaint.color = Color.parseColor("#4B5964")
val screenRect = Rect()
getWindowVisibleDisplayFrame(screenRect)
screenWidth = screenRect.width().toFloat()
val marginBetweenItems = context.resources.getDimension(R.dimen.voip_active_speaker_miniature_margin)
itemWidth = context.resources.getDimension(R.dimen.voip_active_speaker_miniature_size) + marginBetweenItems
Log.d("[Horizontal Scroll Dots] Screen width is $screenWidth and item width is $itemWidth")
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
if (horizontalScrollViewRef > 0) {
try {
horizontalScrollView = (parent as View).findViewById(horizontalScrollViewRef)
horizontalScrollView.setOnScrollChangeListener(scrollListener)
Log.d("[Horizontal Scroll Dots] HorizontalScrollView scroll listener set")
} catch (e: Exception) {
Log.e("[Horizontal Scroll Dots] Failed to find HorizontalScrollView from id $horizontalScrollViewRef: $e")
}
} else {
Log.e("[Horizontal Scroll Dots] No HorizontalScrollView reference given")
}
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
for (i in 0 until count) {
if (i == selected) {
canvas.drawCircle(
(i + 1) * margin + (i * 2 + 1) * radius,
radius,
radius,
selectedDotPaint
)
} else {
canvas.drawCircle(
(i + 1) * margin + (i * 2 + 1) * radius,
radius,
radius,
dotPaint
)
}
}
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val width = ((radius * 2 + margin) * count + margin).toInt()
val height: Int = (radius * 2).toInt()
setMeasuredDimension(width, height)
}
private fun setDotCount(count: Int) {
this.count = count
requestLayout()
invalidate()
}
fun setItemCount(items: Int) {
val itemsPerScreen = (screenWidth / itemWidth)
val dots = ceil(items.toDouble() / itemsPerScreen).toInt()
Log.d("[Horizontal Scroll Dots] Calculated $count for $items items ($itemsPerScreen items fit in screen width), given that screen width is $screenWidth and item width is $itemWidth")
setDotCount(dots)
}
fun setSelectedDot(index: Int) {
selected = index
invalidate()
}
}

View file

@ -0,0 +1,245 @@
/*
* Copyright (c) 2010-2021 Belledonne Communications SARL.
*
* This file is part of linphone-android
* (see https://www.linphone.org).
*
* 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/>.
*/
package org.linphone.activities.voip.views
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.view.View
import android.view.View.OnScrollChangeListener
import android.widget.FrameLayout
import android.widget.HorizontalScrollView
import android.widget.ScrollView
import kotlin.math.ceil
import kotlin.math.roundToInt
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.utils.AppUtils
class ScrollDotsView : View {
private var count = 2
private var selected = 0
private var radius: Float = 5f
private var margin: Float = 2f
private var screenWidth: Float = 0f
private var itemWidth: Float = 0f
private var screenHeight: Float = 0f
private var itemHeight: Float = 0f
private lateinit var dotPaint: Paint
private lateinit var selectedDotPaint: Paint
private var scrollViewRef = 0
private lateinit var scrollView: FrameLayout
private var isHorizontal = false
private val scrollListener = OnScrollChangeListener { v, scrollX, _, _, _ ->
if (isHorizontal) {
if (v !is HorizontalScrollView) {
Log.e("[Scoll Dots] ScrollView reference isn't a HorizontalScrollView!")
return@OnScrollChangeListener
}
val childWidth: Int = v.getChildAt(0).measuredWidth
val scrollViewWidth = v.measuredWidth
val scrollableX = childWidth - scrollViewWidth
if (scrollableX > 0) {
val percent = (scrollX.toFloat() * 100 / scrollableX).toDouble()
if (count > 1) {
val selectedDot = percent / (100 / (count - 1))
val dot = selectedDot.roundToInt()
if (dot != selected) {
setSelectedDot(dot)
}
}
}
} else {
if (v !is ScrollView) {
Log.e("[Scoll Dots] ScrollView reference isn't a ScrollView!")
return@OnScrollChangeListener
}
val childHeight: Int = v.getChildAt(0).measuredHeight
val scrollViewHeight = v.measuredHeight
val scrollableY = childHeight - scrollViewHeight
if (scrollableY > 0) {
val percent = (scrollY.toFloat() * 100 / scrollableY).toDouble()
if (count > 1) {
val selectedDot = percent / (100 / (count - 1))
val dot = selectedDot.roundToInt()
if (dot != selected) {
setSelectedDot(dot)
}
}
}
}
}
constructor(context: Context) : super(context) { init(context) }
constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
init(context)
context.theme.obtainStyledAttributes(
attrs,
R.styleable.ScrollDot,
defStyleAttr, 0
).apply {
try {
radius = getDimension(R.styleable.ScrollDot_dotRadius, 5f)
count = getInt(R.styleable.ScrollDot_dotCount, 1)
val color = getColor(R.styleable.ScrollDot_dotColor, context.resources.getColor(R.color.voip_gray_dots))
dotPaint.color = color
val selectedColor = getColor(R.styleable.ScrollDot_selectedDotColor, context.resources.getColor(R.color.voip_dark_gray))
selectedDotPaint.color = selectedColor
selected = getInt(R.styleable.ScrollDot_selectedDot, 1)
scrollViewRef = getResourceId(R.styleable.ScrollDot_scrollView, 0)
Log.d("[Scroll Dots] ScrollView reference set is $scrollViewRef")
invalidate()
} catch (e: Exception) {
Log.e("[Scroll Dots] $e")
} finally {
recycle()
}
}
}
fun init(context: Context) {
radius = AppUtils.dpToPixels(context, 5f)
margin = AppUtils.dpToPixels(context, 5f)
dotPaint = Paint()
dotPaint.color = Color.parseColor("#D8D8D8")
selectedDotPaint = Paint()
selectedDotPaint.color = Color.parseColor("#4B5964")
val screenRect = Rect()
getWindowVisibleDisplayFrame(screenRect)
screenWidth = screenRect.width().toFloat()
screenHeight = screenRect.height().toFloat()
val marginBetweenItems = context.resources.getDimension(R.dimen.voip_active_speaker_miniature_margin)
itemWidth = context.resources.getDimension(R.dimen.voip_active_speaker_miniature_size) + marginBetweenItems
itemHeight = context.resources.getDimension(R.dimen.voip_active_speaker_miniature_size) + marginBetweenItems
Log.d("[Scroll Dots] Screen size is $screenWidth/$screenHeight and item size is $itemWidth/$itemHeight")
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
if (scrollViewRef > 0) {
try {
scrollView = (parent as View).findViewById(scrollViewRef)
scrollView.setOnScrollChangeListener(scrollListener)
Log.d("[Scroll Dots] ScrollView scroll listener set")
if (scrollView is HorizontalScrollView) {
isHorizontal = true
}
} catch (e: Exception) {
Log.e("[Scroll Dots] Failed to find ScrollView from id $scrollViewRef: $e")
}
} else {
Log.e("[Scroll Dots] No ScrollView reference given")
}
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
for (i in 0 until count) {
if (i == selected) {
val position = (i + 1) * margin + (i * 2 + 1) * radius
canvas.drawCircle(
if (isHorizontal) position else radius,
if (isHorizontal) radius else position,
radius,
selectedDotPaint
)
} else {
val position = (i + 1) * margin + (i * 2 + 1) * radius
canvas.drawCircle(
if (isHorizontal) position else radius,
if (isHorizontal) radius else position,
radius,
dotPaint
)
}
}
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
if (isHorizontal) {
val width = ((radius * 2 + margin) * count + margin).toInt()
val height: Int = (radius * 2).toInt()
setMeasuredDimension(width, height)
} else {
val height = ((radius * 2 + margin) * count + margin).toInt()
val width: Int = (radius * 2).toInt()
setMeasuredDimension(width, height)
}
}
private fun setDotCount(count: Int) {
this.count = count
requestLayout()
invalidate()
}
fun setItemCount(items: Int) {
if (isHorizontal) {
val itemsPerScreen = (screenWidth / itemWidth)
val dots = ceil(items.toDouble() / itemsPerScreen).toInt()
Log.d("[Scroll Dots] Calculated $count for $items items ($itemsPerScreen items fit in screen width), given that screen width is $screenWidth and item width is $itemWidth")
setDotCount(dots)
} else {
val itemsPerScreen = (screenHeight / itemHeight)
val dots = ceil(items.toDouble() / itemsPerScreen).toInt()
Log.d("[Vertical Scroll Dots] Calculated $count for $items items ($itemsPerScreen items fit in screen height), given that screen height is $screenHeight and item height is $itemHeight")
setDotCount(dots)
}
}
fun setSelectedDot(index: Int) {
selected = index
invalidate()
}
}

View file

@ -50,7 +50,7 @@ import org.linphone.R
import org.linphone.activities.GenericActivity
import org.linphone.activities.main.settings.SettingListener
import org.linphone.activities.voip.data.ConferenceParticipantDeviceData
import org.linphone.activities.voip.views.HorizontalScrollDotsView
import org.linphone.activities.voip.views.ScrollDotsView
import org.linphone.contact.ContactAvatarGenerator
import org.linphone.contact.ContactDataInterface
import org.linphone.contact.getPictureUri
@ -641,6 +641,14 @@ fun setConstraintLayoutMargins(view: View, margins: Float) {
view.layoutParams = params
}
@BindingAdapter("android:layout_marginTop")
fun setConstraintLayoutTopMargin(view: View, margins: Float) {
val params = view.layoutParams as ConstraintLayout.LayoutParams
val m = margins.toInt()
params.setMargins(params.leftMargin, m, params.rightMargin, params.bottomMargin)
view.layoutParams = params
}
@BindingAdapter("android:onTouch")
fun View.setTouchListener(listener: View.OnTouchListener) {
setOnTouchListener(listener)
@ -691,11 +699,11 @@ fun setParticipantTextureView(
}
@BindingAdapter("itemCount")
fun HorizontalScrollDotsView.setItems(count: Int) {
fun ScrollDotsView.setItems(count: Int) {
setItemCount(count)
}
@BindingAdapter("selectedDot")
fun HorizontalScrollDotsView.setSelectedIndex(index: Int) {
fun ScrollDotsView.setSelectedIndex(index: Int) {
setSelectedDot(index)
}

View file

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<variable
name="conferenceViewModel"
type="org.linphone.activities.voip.viewmodels.ConferenceViewModel" />
<variable
name="controlsViewModel"
type="org.linphone.activities.voip.viewmodels.ControlsViewModel" />
<variable
name="inflatedVisibility"
type="Integer" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@{controlsViewModel.fullScreenMode || controlsViewModel.pipMode ? @dimen/voip_remote_margin_full_screen : @dimen/voip_remote_margin, default=@dimen/voip_remote_margin}"
android:visibility="@{inflatedVisibility}">
<include
android:id="@+id/header"
layout="@layout/voip_conference_header"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:visibility="@{controlsViewModel.fullScreenMode || controlsViewModel.pipMode ? View.GONE : View.VISIBLE}"
app:conferenceViewModel="@{conferenceViewModel}" />
<include
android:id="@+id/remote_recording"
layout="@layout/voip_remote_recording"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/header"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:visibility="@{conferenceViewModel.isRemotelyRecorded ? View.VISIBLE : View.GONE, default=gone}" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/top_barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="header, remote_recording"/>
<org.linphone.activities.voip.views.ScrollDotsView
android:id="@+id/scroll_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{controlsViewModel.pipMode ? View.GONE : View.VISIBLE}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/top_barrier"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginEnd="5dp"
app:dotColor="@color/voip_gray_dots"
app:dotRadius="5dp"
app:scrollView="@id/miniatures"
app:itemCount="@{conferenceViewModel.conferenceParticipantDevices.size()}"
app:selectedDot="@{0}"
app:selectedDotColor="@color/voip_dark_gray" />
<ScrollView
android:id="@+id/miniatures"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
app:layout_constraintTop_toBottomOf="@id/top_barrier"
app:layout_constraintEnd_toStartOf="@id/scroll_indicator"
app:layout_constraintBottom_toBottomOf="parent"
android:scrollbars="none">
<com.google.android.flexbox.FlexboxLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:alignItems="stretch"
app:entries="@{conferenceViewModel.conferenceParticipantDevices}"
app:flexDirection="column"
app:flexWrap="nowrap"
app:justifyContent="flex_start"
app:layout="@{@layout/voip_conference_participant_remote_active_speaker_miniature}" />
</ScrollView>
<View
android:id="@+id/active_speaker_background"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/top_barrier"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/miniatures"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginTop="@{controlsViewModel.fullScreenMode ? @dimen/margin_0dp : @dimen/voip_active_speaker_top_margin, default=@dimen/voip_active_speaker_top_margin}"
android:background="@drawable/shape_remote_background"
android:onClick="@{() -> controlsViewModel.toggleFullScreen()}"/>
<ImageView
android:id="@+id/speaking_participant_avatar"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
coilVoipContact="@{conferenceViewModel.speakingParticipant}"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintBottom_toBottomOf="@id/active_speaker_background"
app:layout_constraintEnd_toEndOf="@id/active_speaker_background"
app:layout_constraintHeight_max="@dimen/voip_contact_avatar_max_size"
app:layout_constraintStart_toStartOf="@id/active_speaker_background"
app:layout_constraintTop_toTopOf="@id/active_speaker_background"
app:layout_constraintWidth_max="@dimen/voip_contact_avatar_max_size" />
<org.linphone.activities.voip.views.RoundCornersTextureView
android:id="@+id/conference_active_speaker_remote_video"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="@{!conferenceViewModel.isConferenceLocallyPaused &amp;&amp; conferenceViewModel.speakingParticipant.videoEnabled ? View.VISIBLE : View.GONE}"
app:layout_constraintBottom_toBottomOf="@id/active_speaker_background"
app:layout_constraintEnd_toEndOf="@id/active_speaker_background"
app:layout_constraintStart_toStartOf="@id/active_speaker_background"
app:layout_constraintTop_toTopOf="@id/active_speaker_background" />
<TextView
android:id="@+id/speaking_participant_name"
style="@style/call_remote_name_font"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginBottom="10dp"
android:text="@{conferenceViewModel.speakingParticipant.contact.name ?? conferenceViewModel.speakingParticipant.displayName}"
app:layout_constraintBottom_toBottomOf="@id/active_speaker_background"
app:layout_constraintStart_toStartOf="@id/active_speaker_background" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -25,20 +25,6 @@
android:layout_margin="@{controlsViewModel.fullScreenMode || controlsViewModel.pipMode ? @dimen/voip_remote_margin_full_screen : @dimen/voip_remote_margin, default=@dimen/voip_remote_margin}"
android:visibility="@{inflatedVisibility}">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/hinge_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/hinge_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="1" />
<include
android:id="@+id/header"
layout="@layout/voip_conference_header"
@ -72,9 +58,8 @@
app:layout_constraintTop_toBottomOf="@id/top_barrier"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_barrier"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
app:layout_constraintBottom_toTopOf="@id/miniatures"
android:layout_marginTop="@{controlsViewModel.fullScreenMode ? @dimen/margin_0dp : @dimen/voip_active_speaker_top_margin, default=@dimen/voip_active_speaker_top_margin}"
android:background="@drawable/shape_remote_background"
android:onClick="@{() -> controlsViewModel.toggleFullScreen()}"/>
@ -86,7 +71,7 @@
android:contentDescription="@null"
coilVoipContact="@{conferenceViewModel.speakingParticipant}"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintBottom_toTopOf="@id/bottom_barrier"
app:layout_constraintBottom_toTopOf="@id/miniatures"
app:layout_constraintEnd_toEndOf="@id/active_speaker_background"
app:layout_constraintHeight_max="@dimen/voip_contact_avatar_max_size"
app:layout_constraintStart_toStartOf="@id/active_speaker_background"
@ -114,21 +99,13 @@
app:layout_constraintBottom_toBottomOf="@id/active_speaker_background"
app:layout_constraintStart_toStartOf="@id/active_speaker_background" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/bottom_barrier"
android:layout_width="0dp"
android:layout_height="0dp"
app:barrierDirection="top"
app:constraint_referenced_ids="hinge_bottom, miniatures" />
<HorizontalScrollView
android:id="@+id/miniatures"
android:layout_width="0dp"
android:layout_height="@dimen/voip_active_speaker_miniature_size"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/scroll_indicator"
android:layout_marginBottom="5dp"
android:scrollbars="none">
<com.google.android.flexbox.FlexboxLayout
@ -143,7 +120,7 @@
</HorizontalScrollView>
<org.linphone.activities.voip.views.HorizontalScrollDotsView
<org.linphone.activities.voip.views.ScrollDotsView
android:id="@+id/scroll_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -154,7 +131,7 @@
android:layout_marginBottom="5dp"
app:dotColor="@color/voip_gray_dots"
app:dotRadius="5dp"
app:horizontalScrollView="@id/miniatures"
app:scrollView="@id/miniatures"
app:itemCount="@{conferenceViewModel.conferenceParticipantDevices.size()}"
app:selectedDot="@{0}"
app:selectedDotColor="@color/voip_dark_gray" />

View file

@ -14,8 +14,7 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="@dimen/voip_active_speaker_miniature_size"
android:layout_height="@dimen/voip_active_speaker_miniature_size"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:layout_margin="5dp"
android:background="@{!data.isInConference ? @drawable/shape_remote_paused_background : data.videoEnabled ? @drawable/shape_remote_video_background : @drawable/shape_remote_background, default=@drawable/shape_remote_background}"
app:layout_alignSelf="flex_end"
app:layout_flexShrink="0">

View file

@ -75,13 +75,13 @@
</attr>
</declare-styleable>
<declare-styleable name="HorizontalScrollDot">
<declare-styleable name="ScrollDot">
<attr name="dotCount" format="integer" />
<attr name="itemCount" format="integer" />
<attr name="dotColor" format="color" />
<attr name="selectedDotColor" format="color" />
<attr name="selectedDot" format="integer" />
<attr name="dotRadius" format="dimension" />
<attr name="horizontalScrollView" format="reference" />
<attr name="scrollView" format="reference" />
</declare-styleable>
</resources>

View file

@ -61,11 +61,13 @@
<dimen name="voip_conference_participant_mic_muted_icon_size_grid">30dp</dimen>
<dimen name="voip_conference_participant_mic_muted_icon_size_active_speaker">25dp</dimen>
<dimen name="voip_dialog_button_max_width">137dp</dimen>
<dimen name="voip_contact_avatar_max_size">200dp</dimen>
<dimen name="voip_contact_avatar_max_size">180dp</dimen>
<dimen name="voip_contact_avatar_text_size">80sp</dimen>
<dimen name="voip_numpad_button_max_size">60dp</dimen>
<dimen name="voip_conference_audio_only_participant_cell_height">80dp</dimen>
<dimen name="voip_conference_audio_only_participant_avatar_size">40dp</dimen>
<dimen name="conference_schedule_form_field_border_thickness">1dp</dimen>
<dimen name="master_fragment_width">280dp</dimen>
<dimen name="voip_active_speaker_top_margin">10dp</dimen>
<dimen name="margin_0dp">0dp</dimen>
</resources>