Build a custom participant list UI that displays real-time participant information with full control over layout and interactions. This guide demonstrates how to hide the default participant list and create your own using participant events and actions.Documentation Index
Fetch the complete documentation index at: https://cometchat-22654f5b-docs-android-v6-beta2.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The SDK provides participant data through events, allowing you to build custom UIs for:- Participant roster with search and filtering
- Custom participant cards with role badges or metadata
- Moderation dashboards with quick access to controls
- Attendance tracking and engagement monitoring
Prerequisites
- CometChat Calls SDK installed and initialized
- Active call session (see Join Session)
- Basic understanding of RecyclerView and adapters
Step 1: Hide Default Participant List
Configure session settings to hide the default participant list button:- Kotlin
- Java
val sessionSettings = CometChatCalls.SessionSettingsBuilder()
.hideParticipantListButton(true)
.build()
SessionSettings sessionSettings = new CometChatCalls.SessionSettingsBuilder()
.hideParticipantListButton(true)
.build();
Step 2: Create Participant List Layout
Create a layout with RecyclerView for displaying participants:activity_call.xml
activity_call.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Call View Container -->
<FrameLayout
android:id="@+id/callContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Custom Participant List Panel -->
<LinearLayout
android:id="@+id/participantPanel"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:background="#F5F5F5"
android:orientation="vertical"
android:padding="16dp"
android:visibility="gone">
<!-- Header -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingBottom="16dp">
<TextView
android:id="@+id/participantCount"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Participants (0)"
android:textColor="#000000"
android:textSize="18sp"
android:textStyle="bold" />
<ImageButton
android:id="@+id/closeButton"
android:layout_width="32dp"
android:layout_height="32dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Close"
android:src="@android:drawable/ic_menu_close_clear_cancel" />
</LinearLayout>
<!-- Search Bar -->
<EditText
android:id="@+id/searchInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Search participants..."
android:padding="12dp"
android:background="@android:color/white"
android:layout_marginBottom="16dp" />
<!-- Participant List -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/participantRecyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
<!-- Toggle Button -->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/toggleParticipantListButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_margin="16dp"
android:contentDescription="Participants"
android:src="@android:drawable/ic_menu_agenda" />
</RelativeLayout>
item_participant.xml
item_participant.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="12dp"
android:background="?attr/selectableItemBackground">
<!-- Avatar -->
<ImageView
android:id="@+id/participantAvatar"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="12dp"
android:contentDescription="Avatar" />
<!-- Info -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/participantName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="16sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/statusIndicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textColor="#666666" />
</LinearLayout>
</LinearLayout>
<!-- Action Buttons -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton
android:id="@+id/muteButton"
android:layout_width="32dp"
android:layout_height="32dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Mute"
android:src="@android:drawable/ic_lock_silent_mode" />
<ImageButton
android:id="@+id/videoPauseButton"
android:layout_width="32dp"
android:layout_height="32dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Pause Video"
android:src="@android:drawable/ic_menu_camera" />
<ImageButton
android:id="@+id/pinButton"
android:layout_width="32dp"
android:layout_height="32dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Pin"
android:src="@android:drawable/btn_star" />
</LinearLayout>
</LinearLayout>
Step 3: Create Participant Adapter
Build a RecyclerView adapter to display participant data:- Kotlin
- Java
class ParticipantAdapter(
private val onMuteClick: (Participant) -> Unit,
private val onPauseVideoClick: (Participant) -> Unit,
private val onPinClick: (Participant) -> Unit
) : RecyclerView.Adapter<ParticipantAdapter.ViewHolder>() {
private var participants = listOf<Participant>()
private var filteredParticipants = listOf<Participant>()
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val avatar: ImageView = view.findViewById(R.id.participantAvatar)
val name: TextView = view.findViewById(R.id.participantName)
val status: TextView = view.findViewById(R.id.statusIndicator)
val muteButton: ImageButton = view.findViewById(R.id.muteButton)
val videoPauseButton: ImageButton = view.findViewById(R.id.videoPauseButton)
val pinButton: ImageButton = view.findViewById(R.id.pinButton)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_participant, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val participant = filteredParticipants[position]
// Set name
holder.name.text = participant.name
// Load avatar (use your image loading library)
// Glide.with(holder.avatar).load(participant.avatar).into(holder.avatar)
// Build status text
val statusParts = mutableListOf<String>()
if (participant.isAudioMuted) statusParts.add("🔇 Muted")
if (participant.isVideoPaused) statusParts.add("📹 Video Off")
if (participant.isPresenting) statusParts.add("🖥️ Presenting")
if (participant.raisedHandTimestamp > 0) statusParts.add("✋ Hand Raised")
if (participant.isPinned) statusParts.add("📌 Pinned")
holder.status.text = if (statusParts.isEmpty()) "Active" else statusParts.joinToString(" • ")
// Action buttons
holder.muteButton.setOnClickListener { onMuteClick(participant) }
holder.videoPauseButton.setOnClickListener { onPauseVideoClick(participant) }
holder.pinButton.setOnClickListener { onPinClick(participant) }
// Update button states
holder.muteButton.alpha = if (participant.isAudioMuted) 0.5f else 1.0f
holder.videoPauseButton.alpha = if (participant.isVideoPaused) 0.5f else 1.0f
holder.pinButton.alpha = if (participant.isPinned) 1.0f else 0.5f
}
override fun getItemCount() = filteredParticipants.size
fun updateParticipants(newParticipants: List<Participant>) {
participants = newParticipants
filteredParticipants = newParticipants
notifyDataSetChanged()
}
fun filter(query: String) {
filteredParticipants = if (query.isEmpty()) {
participants
} else {
participants.filter {
it.name.contains(query, ignoreCase = true)
}
}
notifyDataSetChanged()
}
}
public class ParticipantAdapter extends RecyclerView.Adapter<ParticipantAdapter.ViewHolder> {
private List<Participant> participants = new ArrayList<>();
private List<Participant> filteredParticipants = new ArrayList<>();
private final OnActionListener listener;
public interface OnActionListener {
void onMuteClick(Participant participant);
void onPauseVideoClick(Participant participant);
void onPinClick(Participant participant);
}
public ParticipantAdapter(OnActionListener listener) {
this.listener = listener;
}
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView avatar;
TextView name;
TextView status;
ImageButton muteButton;
ImageButton videoPauseButton;
ImageButton pinButton;
ViewHolder(View view) {
super(view);
avatar = view.findViewById(R.id.participantAvatar);
name = view.findViewById(R.id.participantName);
status = view.findViewById(R.id.statusIndicator);
muteButton = view.findViewById(R.id.muteButton);
videoPauseButton = view.findViewById(R.id.videoPauseButton);
pinButton = view.findViewById(R.id.pinButton);
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_participant, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Participant participant = filteredParticipants.get(position);
// Set name
holder.name.setText(participant.getName());
// Load avatar (use your image loading library)
// Glide.with(holder.avatar).load(participant.getAvatar()).into(holder.avatar);
// Build status text
List<String> statusParts = new ArrayList<>();
if (participant.isAudioMuted()) statusParts.add("🔇 Muted");
if (participant.isVideoPaused()) statusParts.add("📹 Video Off");
if (participant.isPresenting()) statusParts.add("🖥️ Presenting");
if (participant.getRaisedHandTimestamp() > 0) statusParts.add("✋ Hand Raised");
if (participant.isPinned()) statusParts.add("📌 Pinned");
holder.status.setText(statusParts.isEmpty() ? "Active" : String.join(" • ", statusParts));
// Action buttons
holder.muteButton.setOnClickListener(v -> listener.onMuteClick(participant));
holder.videoPauseButton.setOnClickListener(v -> listener.onPauseVideoClick(participant));
holder.pinButton.setOnClickListener(v -> listener.onPinClick(participant));
// Update button states
holder.muteButton.setAlpha(participant.isAudioMuted() ? 0.5f : 1.0f);
holder.videoPauseButton.setAlpha(participant.isVideoPaused() ? 0.5f : 1.0f);
holder.pinButton.setAlpha(participant.isPinned() ? 1.0f : 0.5f);
}
@Override
public int getItemCount() {
return filteredParticipants.size();
}
public void updateParticipants(List<Participant> newParticipants) {
participants = new ArrayList<>(newParticipants);
filteredParticipants = new ArrayList<>(newParticipants);
notifyDataSetChanged();
}
public void filter(String query) {
if (query.isEmpty()) {
filteredParticipants = new ArrayList<>(participants);
} else {
filteredParticipants = new ArrayList<>();
for (Participant p : participants) {
if (p.getName().toLowerCase().contains(query.toLowerCase())) {
filteredParticipants.add(p);
}
}
}
notifyDataSetChanged();
}
}
Step 4: Implement Participant Events
Listen for participant updates and handle actions in your Activity:- Kotlin
- Java
class CallActivity : AppCompatActivity() {
private lateinit var participantAdapter: ParticipantAdapter
private lateinit var callSession: CallSession
private var isParticipantPanelVisible = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_call)
callSession = CallSession.getInstance()
// Setup RecyclerView
val recyclerView = findViewById<RecyclerView>(R.id.participantRecyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)
participantAdapter = ParticipantAdapter(
onMuteClick = { participant ->
callSession.muteParticipant(participant.uid)
},
onPauseVideoClick = { participant ->
callSession.pauseParticipantVideo(participant.uid)
},
onPinClick = { participant ->
if (participant.isPinned) {
callSession.unPinParticipant()
} else {
callSession.pinParticipant(participant.uid)
}
}
)
recyclerView.adapter = participantAdapter
// Setup search
val searchInput = findViewById<EditText>(R.id.searchInput)
searchInput.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
participantAdapter.filter(s.toString())
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
// Setup toggle button
findViewById<FloatingActionButton>(R.id.toggleParticipantListButton).setOnClickListener {
toggleParticipantPanel()
}
// Setup close button
findViewById<ImageButton>(R.id.closeButton).setOnClickListener {
toggleParticipantPanel()
}
// Listen for participant events
setupParticipantListener()
}
private fun setupParticipantListener() {
callSession.addParticipantEventListener(this, object : ParticipantEventListener() {
override fun onParticipantListChanged(participants: List<Participant>) {
runOnUiThread {
participantAdapter.updateParticipants(participants)
updateParticipantCount(participants.size)
}
}
override fun onParticipantJoined(participant: Participant) {
Log.d(TAG, "${participant.name} joined")
}
override fun onParticipantLeft(participant: Participant) {
Log.d(TAG, "${participant.name} left")
}
override fun onParticipantAudioMuted(participant: Participant) {
// Adapter will update automatically via onParticipantListChanged
}
override fun onParticipantAudioUnmuted(participant: Participant) {
// Adapter will update automatically via onParticipantListChanged
}
override fun onParticipantVideoPaused(participant: Participant) {
// Adapter will update automatically via onParticipantListChanged
}
override fun onParticipantVideoResumed(participant: Participant) {
// Adapter will update automatically via onParticipantListChanged
}
override fun onParticipantHandRaised(participant: Participant) {
// Adapter will update automatically via onParticipantListChanged
}
override fun onParticipantHandLowered(participant: Participant) {
// Adapter will update automatically via onParticipantListChanged
}
})
}
private fun toggleParticipantPanel() {
val panel = findViewById<LinearLayout>(R.id.participantPanel)
isParticipantPanelVisible = !isParticipantPanelVisible
panel.visibility = if (isParticipantPanelVisible) View.VISIBLE else View.GONE
}
private fun updateParticipantCount(count: Int) {
findViewById<TextView>(R.id.participantCount).text = "Participants ($count)"
}
companion object {
private const val TAG = "CallActivity"
}
}
public class CallActivity extends AppCompatActivity {
private ParticipantAdapter participantAdapter;
private CallSession callSession;
private boolean isParticipantPanelVisible = false;
private static final String TAG = "CallActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_call);
callSession = CallSession.getInstance();
// Setup RecyclerView
RecyclerView recyclerView = findViewById(R.id.participantRecyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
participantAdapter = new ParticipantAdapter(new ParticipantAdapter.OnActionListener() {
@Override
public void onMuteClick(Participant participant) {
callSession.muteParticipant(participant.getUid());
}
@Override
public void onPauseVideoClick(Participant participant) {
callSession.pauseParticipantVideo(participant.getUid());
}
@Override
public void onPinClick(Participant participant) {
if (participant.isPinned()) {
callSession.unPinParticipant();
} else {
callSession.pinParticipant(participant.getUid());
}
}
});
recyclerView.setAdapter(participantAdapter);
// Setup search
EditText searchInput = findViewById(R.id.searchInput);
searchInput.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
participantAdapter.filter(s.toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
// Setup toggle button
findViewById(R.id.toggleParticipantListButton).setOnClickListener(v -> toggleParticipantPanel());
// Setup close button
findViewById(R.id.closeButton).setOnClickListener(v -> toggleParticipantPanel());
// Listen for participant events
setupParticipantListener();
}
private void setupParticipantListener() {
callSession.addParticipantEventListener(this, new ParticipantEventListener() {
@Override
public void onParticipantListChanged(List<Participant> participants) {
runOnUiThread(() -> {
participantAdapter.updateParticipants(participants);
updateParticipantCount(participants.size());
});
}
@Override
public void onParticipantJoined(Participant participant) {
Log.d(TAG, participant.getName() + " joined");
}
@Override
public void onParticipantLeft(Participant participant) {
Log.d(TAG, participant.getName() + " left");
}
@Override
public void onParticipantAudioMuted(Participant participant) {
// Adapter will update automatically via onParticipantListChanged
}
@Override
public void onParticipantAudioUnmuted(Participant participant) {
// Adapter will update automatically via onParticipantListChanged
}
@Override
public void onParticipantVideoPaused(Participant participant) {
// Adapter will update automatically via onParticipantListChanged
}
@Override
public void onParticipantVideoResumed(Participant participant) {
// Adapter will update automatically via onParticipantListChanged
}
@Override
public void onParticipantHandRaised(Participant participant) {
// Adapter will update automatically via onParticipantListChanged
}
@Override
public void onParticipantHandLowered(Participant participant) {
// Adapter will update automatically via onParticipantListChanged
}
});
}
private void toggleParticipantPanel() {
LinearLayout panel = findViewById(R.id.participantPanel);
isParticipantPanelVisible = !isParticipantPanelVisible;
panel.setVisibility(isParticipantPanelVisible ? View.VISIBLE : View.GONE);
}
private void updateParticipantCount(int count) {
TextView countView = findViewById(R.id.participantCount);
countView.setText("Participants (" + count + ")");
}
}
Complete Example
Here’s the full implementation with all components:- Kotlin
- Java
class CallActivity : AppCompatActivity() {
private lateinit var participantAdapter: ParticipantAdapter
private lateinit var callSession: CallSession
private var isParticipantPanelVisible = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_call)
callSession = CallSession.getInstance()
setupUI()
setupParticipantListener()
joinCall()
}
private fun setupUI() {
// Setup RecyclerView
val recyclerView = findViewById<RecyclerView>(R.id.participantRecyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)
participantAdapter = ParticipantAdapter(
onMuteClick = { callSession.muteParticipant(it.uid) },
onPauseVideoClick = { callSession.pauseParticipantVideo(it.uid) },
onPinClick = {
if (it.isPinned) callSession.unPinParticipant()
else callSession.pinParticipant(it.uid)
}
)
recyclerView.adapter = participantAdapter
// Setup search
findViewById<EditText>(R.id.searchInput).addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
participantAdapter.filter(s.toString())
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
// Setup buttons
findViewById<FloatingActionButton>(R.id.toggleParticipantListButton)
.setOnClickListener { toggleParticipantPanel() }
findViewById<ImageButton>(R.id.closeButton)
.setOnClickListener { toggleParticipantPanel() }
}
private fun setupParticipantListener() {
callSession.addParticipantEventListener(this, object : ParticipantEventListener() {
override fun onParticipantListChanged(participants: List<Participant>) {
runOnUiThread {
participantAdapter.updateParticipants(participants)
findViewById<TextView>(R.id.participantCount).text =
"Participants (${participants.size})"
}
}
override fun onParticipantJoined(participant: Participant) {
Toast.makeText(this@CallActivity,
"${participant.name} joined", Toast.LENGTH_SHORT).show()
}
override fun onParticipantLeft(participant: Participant) {
Toast.makeText(this@CallActivity,
"${participant.name} left", Toast.LENGTH_SHORT).show()
}
})
}
private fun joinCall() {
val sessionSettings = CometChatCalls.SessionSettingsBuilder()
.hideParticipantListButton(true)
.setTitle("Team Meeting")
.build()
val callContainer = findViewById<FrameLayout>(R.id.callContainer)
CometChatCalls.joinSession(
sessionId = "SESSION_ID",
sessionSettings = sessionSettings,
view = callContainer,
context = this,
listener = object : CometChatCalls.CallbackListener<Void>() {
override fun onSuccess(p0: Void?) {
Log.d(TAG, "Joined call successfully")
}
override fun onError(exception: CometChatException) {
Log.e(TAG, "Failed to join: ${exception.message}")
Toast.makeText(this@CallActivity,
"Failed to join call", Toast.LENGTH_SHORT).show()
}
}
)
}
private fun toggleParticipantPanel() {
val panel = findViewById<LinearLayout>(R.id.participantPanel)
isParticipantPanelVisible = !isParticipantPanelVisible
panel.visibility = if (isParticipantPanelVisible) View.VISIBLE else View.GONE
}
companion object {
private const val TAG = "CallActivity"
}
}
public class CallActivity extends AppCompatActivity {
private ParticipantAdapter participantAdapter;
private CallSession callSession;
private boolean isParticipantPanelVisible = false;
private static final String TAG = "CallActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_call);
callSession = CallSession.getInstance();
setupUI();
setupParticipantListener();
joinCall();
}
private void setupUI() {
// Setup RecyclerView
RecyclerView recyclerView = findViewById(R.id.participantRecyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
participantAdapter = new ParticipantAdapter(new ParticipantAdapter.OnActionListener() {
@Override
public void onMuteClick(Participant participant) {
callSession.muteParticipant(participant.getUid());
}
@Override
public void onPauseVideoClick(Participant participant) {
callSession.pauseParticipantVideo(participant.getUid());
}
@Override
public void onPinClick(Participant participant) {
if (participant.isPinned()) {
callSession.unPinParticipant();
} else {
callSession.pinParticipant(participant.getUid());
}
}
});
recyclerView.setAdapter(participantAdapter);
// Setup search
EditText searchInput = findViewById(R.id.searchInput);
searchInput.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
participantAdapter.filter(s.toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
// Setup buttons
findViewById(R.id.toggleParticipantListButton).setOnClickListener(v ->
toggleParticipantPanel());
findViewById(R.id.closeButton).setOnClickListener(v ->
toggleParticipantPanel());
}
private void setupParticipantListener() {
callSession.addParticipantEventListener(this, new ParticipantEventListener() {
@Override
public void onParticipantListChanged(List<Participant> participants) {
runOnUiThread(() -> {
participantAdapter.updateParticipants(participants);
TextView countView = findViewById(R.id.participantCount);
countView.setText("Participants (" + participants.size() + ")");
});
}
@Override
public void onParticipantJoined(Participant participant) {
Toast.makeText(CallActivity.this,
participant.getName() + " joined", Toast.LENGTH_SHORT).show();
}
@Override
public void onParticipantLeft(Participant participant) {
Toast.makeText(CallActivity.this,
participant.getName() + " left", Toast.LENGTH_SHORT).show();
}
});
}
private void joinCall() {
SessionSettings sessionSettings = new CometChatCalls.SessionSettingsBuilder()
.hideParticipantListButton(true)
.setTitle("Team Meeting")
.build();
FrameLayout callContainer = findViewById(R.id.callContainer);
CometChatCalls.joinSession(
"SESSION_ID",
sessionSettings,
callContainer,
this,
new CometChatCalls.CallbackListener<Void>() {
@Override
public void onSuccess(Void unused) {
Log.d(TAG, "Joined call successfully");
}
@Override
public void onError(CometChatException e) {
Log.e(TAG, "Failed to join: " + e.getMessage());
Toast.makeText(CallActivity.this,
"Failed to join call", Toast.LENGTH_SHORT).show();
}
}
);
}
private void toggleParticipantPanel() {
LinearLayout panel = findViewById(R.id.participantPanel);
isParticipantPanelVisible = !isParticipantPanelVisible;
panel.setVisibility(isParticipantPanelVisible ? View.VISIBLE : View.GONE);
}
}
Participant Object Reference
Participant Object Reference
| Property | Type | Description |
|---|---|---|
uid | String | Unique identifier (CometChat user ID) |
name | String | Display name |
avatar | String | URL of avatar image |
pid | String | Participant ID for this call session |
role | String | Role in the call |
audioMuted | Boolean | Whether audio is muted |
videoPaused | Boolean | Whether video is paused |
isPinned | Boolean | Whether pinned in layout |
isPresenting | Boolean | Whether screen sharing |
raisedHandTimestamp | Long | Timestamp when hand was raised (0 if not raised) |