新闻资讯

新闻资讯 行业动态

Android端实现多人音视频聊天之分屏

编辑:008     时间:2020-02-22

根据前期技术调研,分屏显示最好的方式是采用瀑布流结合动态聊天窗实现,这样比较方便的能够适应UI的变化。所谓瀑布流,就是目前比较流行的一种列表布局,会在界面上呈现参差不齐的多栏布局。我们先实现一个瀑布流:

瀑布流的实现方式很多,本文采用结合 GridLayoutManager的RecyclerView 来实现。我们首先自定义一个 RecyclerView,命名为 GridVideoViewContainer。核心代码如下:

int count = uids.size(); if (count <= 2) { 
    // 只有本地视频或聊天室内只有另外一个人
    this.setLayoutManager(new LinearLayoutManager(activity.getApplicationContext(), orientation, false));
} else if (count > 2) {
    // 多人聊天室
    int itemSpanCount = getNearestSqrt(count);
    this.setLayoutManager(new GridLayoutManager(activity.getApplicationContext(), itemSpanCount, orientation, false));
}

根据上面的代码可以看出,在聊天室里只有自己的本地视频或者只有另外一个人的时候,采用 LinearLayoutManager,这样的布局其实与前文的一对一聊天类似;而在真正意义的多人聊天室里,则采用 GridLayoutManager 实现瀑布流,其中 itemSpanCount 就是瀑布流的列数。

有了一个可用的瀑布流之后,下面我们就可以实现动态聊天窗了: 动态聊天窗的要点在于 item 的大小由视频的宽高比决定,因此 Adapter 及其对应的 layout 就该注意不要写死尺寸。在 Adapter 里控制 item 具体尺寸的代码如下:

if (force || mItemWidth == 0 || mItemHeight == 0) {
    WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    DisplayMetrics outMetrics = new DisplayMetrics();
    windowManager.getDefaultDisplay().getMetrics(outMetrics);

    int count = uids.size();
    int DividerX = 1;
    int DividerY = 1; if (count == 2) {
        DividerY = 2;
    } else if (count >= 3) {
        DividerX = getNearestSqrt(count);
        DividerY = (int) Math.ceil(count * 1.f / DividerX);
    }

    int width = outMetrics.widthPixels;
    int height = outMetrics.heightPixels; if (width > height) {
        mItemWidth = width / DividerY;
        mItemHeight = height / DividerX;
    } else {
        mItemWidth = width / DividerX;
        mItemHeight = height / DividerY;
    }
}

以上代码根据视频的数量确定了列数和行数,然后根据列数和屏幕宽度确定了视频的宽度,接着根据视频的宽高比和视频宽度确定了视频高度。同时也考虑了手机的横竖屏情况(就是if (width > height)这行代码)。

该 Adapter 对应的 layout 的代码如下:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/user_control_mask" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">

    <ImageView
        android:id="@+id/default_avatar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="gone" android:src="@drawable/icon_default_avatar" android:contentDescription="DEFAULT_AVATAR" />

    <ImageView
        android:id="@+id/indicator" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_alignParentBottom="true" android:layout_marginBottom="@dimen/video_indicator_bottom_margin" android:contentDescription="VIDEO_INDICATOR" />

    <LinearLayout
        android:id="@+id/video_info_container" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_marginTop="24dp" android:layout_marginStart="15dp" android:layout_marginLeft="15dp" android:visibility="gone" android:orientation="vertical">

        <TextView
            android:id="@+id/video_info_metadata" android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" style="@style/NotificationUIText" />
    </LinearLayout>

</RelativeLayout> 

我们可以看到,layout 中有关尺寸的属性都 是wrap_content,这就使得 item 大小随视频宽高比变化成为可能。

把分屏的布局写好之后,我们就可以在每一个 item 上播放聊天视频了。



原文链接:https://juejin.im/post/5e4cfb36518825494707dc90
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

回复列表

相关推荐