Android技术分享| Android 自定义View多人视频通话控件

我自横刀向天笑,去留肝胆两昆仑。这篇文章主要讲述Android技术分享| Android 自定义View多人视频通话控件相关的知识,希望能为你提供帮助。
【android 自定义View】多人视频通话控件

Android技术分享| Android 自定义View多人视频通话控件

文章图片

*以上图片截自微信等待中界面
等待中界面上图是微信多人视频通话时未接通的界面状态,可见每个人的 View 中大致需包含了以下元素。
  1. 头像
  2. 昵称
  3. Loading View
  4. 视频 View
  5. 音频状态 icon
所以,我们先写好每个人的布局。如下
< merge xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_ android:layout_ android:background="#2C3033" tools:parentTag="android.widget.RelativeLayout"> < !--视频View--> < TextureView android:id="@+id/video_view" android:layout_ android:layout_> < /TextureView> < !--头像--> < ImageView android:id="@+id/iv_avatar" android:src="https://www.songbingjia.com/android/@drawable/avatar" android:layout_ android:layout_> < /ImageView> < !--名字--> < TextView android:id="@+id/tv_user_name" android:layout_ android:layout_ android:layout_alignParentBottom="true" android:layout_margin="20dp" tools:text="UserName" android:background="@android:color/transparent" android:textColor="@android:color/white" android:textSize="14sp" /> < !--音频状态Icon--> < ImageView android:id="@+id/iv_audio_enable" android:layout_ android:layout_ android:layout_alignParentRight="true" android:layout_alignParentBottom="true" android:layout_margin="20dp" android:src="https://www.songbingjia.com/android/@drawable/mic_enable"> < /ImageView> < !--Loading--> < ImageView android:id="@+id/iv_loading" android:layout_ android:layout_ android:layout_centerInParent="true" android:src="https://www.songbingjia.com/android/@drawable/loading"> < /ImageView> < /merge>

GroupUserVideoLayout接着定义自定义View类,GroupUserVideoLayout 添加一些基本的方法。
/** * 多人视频通话中每个用户的布局 */ class GroupUserVideoLayout @JvmOverloads constructor(mContext:Context): RelativeLayout(mContext) private var videoView:TextureView private var ivAvatar:ImageView private var ivAudio:ImageView private var tvName:TextView private var ivLoading:ImageViewinit val root = LayoutInflater.from(mContext).inflate(R.layout.layout_gv_layout,this) videoView = root.findViewById(R.id.video_view) ivAvatar = root.findViewById(R.id.iv_avatar) ivAudio = root.findViewById(R.id.iv_audio_enable) tvName = root.findViewById(R.id.tv_user_name) ivLoading = root.findViewById(R.id.iv_loading)//设置昵称 fun setUserName(userName:String) tvName.text = userName//设置头像 fun setAvatar(avatarUrl:String) ivAvatar.loadUrl(avatarUrl)//设置音频图标状态 fun enableAudio(enable:Boolean) ivAudio.visibility = if (enable) VISIBLE else GONE//设置LoadingView状态 fun setLoadingState(open:Boolean) ivLoading.visibility = if (open) VISIBLE else GONE

接听后?接听后,对应的设置每个人的头像昵称,去掉 Loading,显示视频。接下来就是要定义多个人进出时,布局的变化了。
- 2个人的时候,左右对齐均分显示 - 3个人的时候品字型显示 - 4个人的时候上下2个均分显示 - 5个人以上则九宫格显示

GroupVideoLayoutManager定义 GroupVideoLayoutManager ,这个是在外部直接使用的,里面应当有查找、添加用户,移除用户,根据人数更新布局位置等功能。
class GroupVideoLayoutManager constructor(mContext: Context): RelativeLayout(mContext) //自己的ID var selfId:String="" private val userLayoutList = mutableListOf< LayoutEntity> () private var userCount = 0 private val MAX_USER = 8private val oneUserParamList by lazyLayoutUtils.get1UserParam(mContext,width,height) private val twoUserParamList by lazyLayoutUtils.get2UserParam(mContext,width,height) private val threeUserParamList by lazyLayoutUtils.get3UserParam(mContext,width,height) private val fourUserParamList by lazyLayoutUtils.get4UserParam(mContext,width,height) private val nineUserParamList by lazyLayoutUtils.get9UserParam(mContext,width,height) /** * 根据uid 查找对应的View */ fun findUser(uid:String):GroupUserVideoLayout? userLayoutList.findit.userId==uid ?.letlayoutEntity-> layoutEntity.layout?.let return it ?:let return null?:let return null/** * 根据uid 添加对应的View */ fun addUser(uid:String):GroupUserVideoLayout? if (userCount> MAX_USER) return nullval layout = GroupUserVideoLayout(context) userLayoutList.add(LayoutEntity(layout,uid)) userCount++ post updateLayout()return layout/** * 根据uid 移除对应View */ fun removeUser(uid:String) userLayoutList.findit.userId==uid ?.let userLayoutList.remove(it) userCount--//更新布局位置 private fun updateLayout() if (userLayoutList.isNullOrEmpty()) returnval paramsList:ArrayList< LayoutParams> when(userCount) 1-> paramsList = oneUserParamList userLayoutList[0].layout?.layoutParams = paramsList[0] return2-> paramsList = twoUserParamList3-> paramsList = threeUserParamList4-> paramsList = fourUserParamListelse-> paramsList = nineUserParamListvar layoutIndex = if (selfId.isEmpty()) 0 else 1 userLayoutList.forEach if (it.userId == selfId) it.layout?.layoutParams = paramsList[0] else if (layoutIndex< paramsList.size) it.layout?.layoutParams = paramsList[layoutIndex++]private inner class LayoutEntity var layout: GroupUserVideoLayout? = null var userId = ""constructor(layout: GroupUserVideoLayout?, userId: String) this.layout = layout this.userId = userIdoverride fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) val widthSize = MeasureSpec.getSize(widthMeasureSpec) val heightSize = MeasureSpec.getSize(heightMeasureSpec) if (widthSize == 0 & & heightSize == 0) super.onMeasure(widthMeasureSpec, heightMeasureSpec) val minSize = Math.min(measuredWidth, measuredHeight) setMeasuredDimension(minSize, minSize) returnval size: Int size = if (widthSize == 0 || heightSize == 0) Math.max(widthSize, heightSize) else Math.min(widthSize, heightSize)val newMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY) super.onMeasure(newMeasureSpec, newMeasureSpec)

?以上就实现了类似微信视频通话界面的自定义View,具体使用效果会在下一期的文章所介绍的demo中体现~敬请期待!
Android技术分享| Android 自定义View多人视频通话控件

文章图片

【Android技术分享| Android 自定义View多人视频通话控件】?

    推荐阅读