David Liu

tabs for multiple participants

... ... @@ -44,6 +44,7 @@ dependencies {
implementation "androidx.viewpager2:viewpager2:1.0.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${versions.androidx_lifecycle}"
implementation "androidx.lifecycle:lifecycle-common-java8:${versions.androidx_lifecycle}"
implementation 'com.google.android.material:material:1.3.0'
implementation "com.xwray:groupie:${versions.groupie}"
implementation "com.xwray:groupie-viewbinding:${versions.groupie}"
implementation 'com.snakydesign.livedataextensions:lives:1.3.0'
... ...
... ... @@ -5,6 +5,7 @@ import android.os.Bundle
import android.os.Parcelable
import androidx.appcompat.app.AppCompatActivity
import com.github.ajalt.timberkt.Timber
import com.google.android.material.tabs.TabLayoutMediator
import com.snakydesign.livedataextensions.combineLatest
import com.xwray.groupie.GroupieAdapter
import io.livekit.android.sample.databinding.CallActivityBinding
... ... @@ -19,6 +20,7 @@ class CallActivity : AppCompatActivity() {
CallViewModel(args.url, args.token, application)
}
lateinit var binding: CallActivityBinding
var tabLayoutMediator: TabLayoutMediator? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
... ... @@ -29,6 +31,7 @@ class CallActivity : AppCompatActivity() {
// Viewpager setup
val adapter = GroupieAdapter()
binding.viewPager.apply {
this.adapter = adapter
}
... ... @@ -38,9 +41,19 @@ class CallActivity : AppCompatActivity() {
viewModel.remoteParticipants
) { room, participants -> room to participants }
.observe(this) {
tabLayoutMediator?.detach()
tabLayoutMediator = null
val (room, participants) = it
val items = participants.map { participant -> ParticipantItem(room, participant) }
adapter.update(items)
tabLayoutMediator =
TabLayoutMediator(binding.tabs, binding.viewPager) { tab, position ->
tab.text = participants[position].name
}
tabLayoutMediator?.attach()
}
val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
... ... @@ -60,7 +73,6 @@ class CallActivity : AppCompatActivity() {
}
}
companion object {
const val KEY_ARGS = "args"
}
... ...
... ... @@ -10,6 +10,8 @@ import io.livekit.android.room.track.RemoteVideoTrackPublication
import io.livekit.android.room.track.VideoTrack
import io.livekit.android.room.track.VideoTrackPublication
import io.livekit.android.sample.databinding.ParticipantItemBinding
import org.webrtc.VideoFrame
import org.webrtc.VideoSink
class ParticipantItem(
val room: Room,
... ... @@ -61,6 +63,12 @@ class ParticipantItem(
videoBound = true
Timber.v { "adding renderer to $videoTrack" }
videoTrack.addRenderer(object : VideoSink {
override fun onFrame(frame: VideoFrame?) {
Timber.v { "$frame" }
}
})
videoTrack.addRenderer(viewBinding.renderer)
}
... ...
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.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="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="48dp"
app:layout_constraintTop_toTopOf="parent"
app:tabMode="auto" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/tabs" />
<!--
<org.webrtc.SurfaceViewRenderer
... ... @@ -15,4 +25,4 @@
android:layout_gravity="bottom|end"
android:layout_margin="16dp" />
-->
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
... ...