Live Stream List Feed
Feature Overview
The live stream list waterfall page mainly shows all online video live streaming and audio chat rooms in this application. The waterfall layout interface supports video stream preview without entering the room. It supports single-column and two-column waterfall layouts, pull-down refresh, swipe playback, etc. This document describes how to complete the access work for the waterfall page within 10 minutes.
two-column waterfall layout | single-column waterfall layout |
![]() |
![]() |
Note:
The two-column waterfall layout defaults to entering 2 rooms simultaneously, displaying 2 live streaming room previews in the middle. The single-column waterfall layout defaults to entering 1 room.
When previewing multiple rooms simultaneously, the preview duration of each room is counted into the audience's audio and video duration.
Feature Integration
Note:
1.Note: Before completing the feature integration, you must first complete the integration steps in the overview.
2.The video preloading feature of Waterfall Flow requires the corresponding application (SDKAppID) to be Free Trial or Pro to be usable.
3.When the audience previews the live content outside the live streaming room, the preview duration will be counted into the audience's audio and video duration.
Creating a Waterfall Flow View and Initialization (Choose to Use One Column or Two-Column Waterfall Layout Here)
val mLiveListView = LiveListView(context)mLiveListView.init(this, LiveListViewDefine.Style.DOUBLE_COLUMN)
LiveListView mLiveListView = new LiveListView(this);mLiveListView.init(this, LiveListViewDefine.Style.DOUBLE_COLUMN);
Loading the Waterfall Flow View Into an Activity or a Specific Layout
setContentView(mLiveListView)
setContentView(mLiveListView);
Listening to Waterfall Flow Item Click Event
mLiveListView.setOnItemClickListener { view, liveInfo ->// Here you can redirect to the live room interfaceenterRoom(liveInfo)}
mLiveListView.setOnItemClickListener((view, liveInfo) -> {// Here you can redirect to the live room interfaceenterRoom(liveInfo);});
Feature Customization
Implementing a Custom Data Source for a Waterfall Stream List
The waterfall layout component uses RoomEngine live stream list data by default. If your backend has a separate live list, you can integrate it via the following way:
val dataSource = object : TUILiveListDataSource() {override fun fetchLiveList(param: LiveListViewDefine.FetchLiveListParam,callback: LiveListViewDefine.LiveListCallback) {// Connect to your own business backend and return data to the UI component in the following formatval liveInfoList = mutableListOf<TUILiveListManager.LiveInfo>()val liveInfo = TUILiveListManager.LiveInfo().apply {roomInfo = TUIRoomDefine.RoomInfo().apply {roomId = "live_123456"name = "live_123456"}}liveInfoList.add(liveInfo)val cursor = "aabbccdd"callback.onSuccess(cursor, liveInfoList)}}mLiveListView.init(this, LiveListViewDefine.Style.SINGLE_COLUMN, null, dataSource)
TUILiveListDataSource dataSource = new TUILiveListDataSource(){@Overridepublic void fetchLiveList(LiveListViewDefine.FetchLiveListParam param, LiveListViewDefine.LiveListCallback callback) {//Connect to your own business backend and return data to the UI component in the following formatList<TUILiveListManager.LiveInfo> liveInfoList = new ArrayList<>();TUILiveListManager.LiveInfo liveInfo = new TUILiveListManager.LiveInfo();liveInfo.roomInfo = new TUIRoomDefine.RoomInfo();liveInfo.roomInfo.roomId = "live_123456";liveInfo.roomInfo.name = "live_123456";liveInfoList.add(liveInfo);String cursor = "aabbccdd";callback.onSuccess(cursor, liveInfoList);}};mLiveListView.init(this, LiveListViewDefine.Style.SINGLE_COLUMN, null, dataSource);
Implementing Waterfall Flow with Custom Widgets
At the bottom of the waterfall layout is the video stream image/live cover. The default UI is as follows. The 3D stickers at the top support customization, and the UI can be customized based on the returned data.
two-column waterfall layout | single-column waterfall layout |
![]() |
![]() |
val liveListViewAdapter = object : LiveListViewDefine.LiveListViewAdapter() {override fun createLiveInfoView(liveInfo: TUILiveListManager.LiveInfo): View {// Custom widget viewval widgetView = CustomView(context)widgetView.init(liveInfo)return widgetView}override fun updateLiveInfoView(view: View, liveInfo: TUILiveListManager.LiveInfo) {// Refresh the data bound to the widget viewval widgetView = view as CustomViewwidgetView.updateLiveInfoView(liveInfo)}}mLiveListView.init(this, LiveListViewDefine.Style.SINGLE_COLUMN, liveListViewAdapter, null)
LiveListViewDefine.LiveListViewAdapter liveListViewAdapter = new LiveListViewDefine.LiveListViewAdapter() {@Overridepublic View createLiveInfoView(TUILiveListManager.LiveInfo liveInfo) {// Custom widget viewCustomView widgetView = new CustomView(mContext);widgetView.init(liveInfo);return widgetView;}@Overridepublic void updateLiveInfoView(View view, TUILiveListManager.LiveInfo liveInfo) {// Refresh the data bound to the widget viewCustomView widgetView = (CustomView) view;widgetView.updateLiveInfoView(liveInfo);}};mLiveListView.init(this, LiveListViewDefine.Style.SINGLE_COLUMN, liveListViewAdapter, null);