工作中需要实现一个类似微信多人视频通话功能的界面,分别使用自定义viewgroup和自定义layoutmanager的方式进行了实现。最终工作中采用了layoutmanager,因为可以使用payload更新单个布局控件,效率更好。下面放出两种具体的实现效果代码。

1、使用自定义viewgroup方式实现

下面是三个人通话时候的效果,其他的可以参考微信多人音视频通话界面。

package com.dnaer.android.telephone.widgets;

import android.content.context;

import android.os.build;

import android.support.annotation.requiresapi;

import android.util.attributeset;

import android.util.displaymetrics;

import android.view.view;

import android.view.viewgroup;

import android.view.windowmanager;

import com.anbetter.log.mlog;

public class multivideochatlayout extends viewgroup implements commlayoutadapter.ondatachangedlistener {

private commlayoutadapter mcommlayoutadapter;

private int mscreenwidth;

//人数为2,3,4状态下的宽高度

private int msizemodel1;

//人数为5,6,7,8,9状态下的宽高度

private int msizemodel2;

public multivideochatlayout(context context) {

this(context, null);

}

public multivideochatlayout(context context, attributeset attrs) {

this(context, attrs, 0);

}

public multivideochatlayout(context context, attributeset attrs, int defstyleattr) {

super(context, attrs, defstyleattr);

initialize(context);

}

@requiresapi(api = build.version_codes.lollipop)

public multivideochatlayout(context context, attributeset attrs, int defstyleattr, int defstyleres) {

super(context, attrs, defstyleattr, defstyleres);

initialize(context);

}

private void initialize(context context) {

windowmanager wm = (windowmanager) context.getsystemservice(context.window_service);

displaymetrics metrics = new displaymetrics();

wm.getdefaultdisplay().getmetrics(metrics);

mscreenwidth = metrics.widthpixels;

msizemodel1 = mscreenwidth / 2;

msizemodel2 = mscreenwidth / 3;

}

@override

protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {

//宽度默认给屏幕的宽度,高度直接取宽度,形成一个正方形

final int width = measurespec.makemeasurespec(mscreenwidth, measurespec.exactly);

final int height = measurespec.makemeasurespec(mscreenwidth, measurespec.exactly);

setmeasureddimension(width, height);

mlog.d("width: " + width + ", height:" + height);

final int childwidth = measurespec.makemeasurespec(mscreenwidth / 3, measurespec.exactly);

final int childheight = measurespec.makemeasurespec(mscreenwidth / 3, measurespec.exactly);

final int childwidth2 = measurespec.makemeasurespec(mscreenwidth / 2, measurespec.exactly);

final int childheight2 = measurespec.makemeasurespec(mscreenwidth / 2, measurespec.exactly);

if (getchildcount() > 4) {

for (int i = 0; i < getchildcount(); i++) {

view child = getchildat(i);

child.measure(childwidth, childheight);

}

} else {

for (int i = 0; i < getchildcount(); i++) {

view child = getchildat(i);

child.measure(childwidth2, childheight2);

}

}

}

@override

protected void onlayout(boolean changed, int l, int t, int r, int b) {

if (getchildcount() <= 4) {

layoutmodel1();

} else {

layoutmodel2();

}

}

private void layoutmodel2() {

int currentwidth = 0;

for (int i = 0; i < getchildcount(); i++) {

view item = getchildat(i);

if (i % 3 == 0) {

currentwidth = 0;

item.layout(0, i / 3 * msizemodel2, msizemodel2, i / 3 * msizemodel2 + msizemodel2);

} else {

item.layout(currentwidth + msizemodel2, i / 3 * msizemodel2, currentwidth + 2 * msizemodel2, i / 3 * msizemodel2 + msizemodel2);

currentwidth = currentwidth + msizemodel2;

}

}

}

private void layoutmodel1() {

if (getchildcount() == 3) {

for (int i = 0; i < getchildcount(); i++) {

view item = getchildat(i);

mlog.d("width: " + item.getmeasuredwidth() + ", height: " + item.getmeasuredheight() + ", msizemodel1: " + msizemodel1);

if (i == 0) {

item.layout(0, 0, msizemodel1, msizemodel1);

} else if (i == 1) {

item.layout(msizemodel1, 0, msizemodel1 * 2, msizemodel1);

} else if (i == 2) {

item.layout(msizemodel1 / 2, msizemodel1, msizemodel1 + msizemodel1 / 2, msizemodel1 * 2);

}

}

} else {

for (int i = 0; i < getchildcount(); i++) {

view item = getchildat(i);

if (i % 2 == 0) {

item.layout(0, i / 2 * msizemodel1, msizemodel1, i / 2 * msizemodel1 + msizemodel1);

} else {

item.layout(msizemodel1, i / 2 * msizemodel1, 2 * msizemodel1, i / 2 * msizemodel1 + msizemodel1);

}

}

}

}

public void setadapter(commlayoutadapter adapter) {

mcommlayoutadapter = adapter;

mcommlayoutadapter.setondatachangedlistener(this);

changedadapter();

}

@override

public void onchanged() {

changedadapter();

}

private void changedadapter() {

removeallviews();

commlayoutadapter layoutadapter = mcommlayoutadapter;

for (int i = 0; i < layoutadapter.getcount(); i++) {

view view = layoutadapter.getview(this, i, layoutadapter.getitem(i));

view.setduplicateparentstateenabled(true);

addview(view);

}

}

}

2、使用自定义layoutmanager方式实现

package org.fireking.customgridlayoutmanager

import android.content.res.resources

import android.support.v7.widget.recyclerview

import java.lang.illegalargumentexception

class multichatlayoutmanager : recyclerview.layoutmanager() {

private var leftmargin = 0

private var rightmargin = 0

private var mscreenwidth = 0

override fun generatedefaultlayoutparams(): recyclerview.layoutparams {

return recyclerview.layoutparams(recyclerview.layoutparams.wrap_content, recyclerview.layoutparams.wrap_content)

}

override fun onlayoutchildren(recycler: recyclerview.recycler?, state: recyclerview.state?) {

super.onlayoutchildren(recycler, state)

if (itemcount == 0) {

detachandscrapattachedviews(recycler!!)

return

}

if (childcount == 0 && state!!.isprelayout) {

return

}

val params = recycler!!.getviewforposition(0).layoutparams as recyclerview.layoutparams

leftmargin = params.leftmargin

rightmargin = params.rightmargin

detachandscrapattachedviews(recycler)

layoutitem(recycler)

}

private fun layoutitem(recycler: recyclerview.recycler) {

if (itemcount > 9) {

throw illegalargumentexception("${javaclass.simplename}最多支持9个item布局, 请检查你的item个数是否正确")

}

mscreenwidth = resources.getsystem().displaymetrics.widthpixels

val itemsize = if (itemcount > 4) {

mscreenwidth / 3

} else {

mscreenwidth / 2

}

if (itemcount <= 4) {

if (itemcount == 3) {

for (i in 0 until itemcount) {

val view = recycler.getviewforposition(i)

addview(view) // 因为detach过所以重新添加

measurechildwithmargins(view, 0, 0)

when (i) {

0 -> layoutdecoratedwithmargins(view, 0, 0, itemsize, itemsize)

1 -> layoutdecoratedwithmargins(view, itemsize, 0, itemsize * 2, itemsize)

else -> layoutdecoratedwithmargins(

view,

itemsize / 2,

itemsize,

itemsize + itemsize / 2,

itemsize * 2

)

}

}

} else {

for (i in 0 until itemcount) {

val view = recycler.getviewforposition(i)

addview(view) // 因为detach过所以重新添加

measurechildwithmargins(view, 0, 0)

if (i % 2 == 0) {

layoutdecoratedwithmargins(view, 0, i / 2 * itemsize, itemsize, i / 2 * itemsize + itemsize)

} else {

layoutdecoratedwithmargins(

view,

itemsize,

i / 2 * itemsize,

2 * itemsize,

i / 2 * itemsize + itemsize

)

}

}

}

} else {

var currentwidth = 0

for (i in 0 until itemcount) {

val view = recycler.getviewforposition(i)

addview(view) // 因为detach过所以重新添加

measurechildwithmargins(view, 0, 0)

if (i % 3 == 0) {

currentwidth = 0

layoutdecoratedwithmargins(view, 0, i / 3 * itemsize, itemsize, i / 3 * itemsize + itemsize)

} else {

layoutdecoratedwithmargins(

view,

currentwidth + itemsize,

i / 3 * itemsize,

currentwidth + 2 * itemsize,

i / 3 * itemsize + itemsize

)

currentwidth += itemsize

}

}

}

}

//因为这个布局不需要有滚动,所以直接将横竖两个方向的滚动全部取消了

override fun canscrollhorizontally(): boolean {

return false

}

override fun canscrollvertically(): boolean {

return false

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持萬仟网。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

android 微信缩小通话界面_Android仿微信多人音视频通话界面相关推荐

  1. 仿微信多人音视频通话界面

    工作中需要实现一个类似微信多人视频通话功能的界面,分别使用自定义viewgroup和自定义layoutManager的方式进行了实现.最终工作中采用了layoutManager,因为可以使用paylo ...

  2. android 微信浮窗实现_Android仿微信视屏悬浮窗效果

    在项目中需要对接入的腾讯云音视频,可以悬浮窗显示,悬浮窗可拖拽,并且在悬浮窗不影响其他的activity的焦点. 这个大神的文章Android基于腾讯云实时音视频仿微信视频通话最小化悬浮,他讲的是视频 ...

  3. android仿微信下拉二楼_Android仿微信下拉列表实现

    本文要实现微信6.1中点击顶部菜单栏的"+"号按钮时,会弹出一个列表框.这里用的了Activity实现,其实最好的方法可以用ActionBar,不过这货好像只支持3.0以后的版本. ...

  4. java实现仿微信app聊天功能_Android仿微信语音聊天功能

    本文实例讲述了Android仿微信语音聊天功能代码.分享给大家供大家参考.具体如下: 项目效果如下: 具体代码如下: AudioManager.java package com.xuliugen.we ...

  5. 安卓开发仿微信图片拖拽_Android仿微信朋友圈图片浏览器(支持图片手势缩放,拖动)...

    [实例简介] Android仿微信朋友圈图片浏览器(支持图片手势缩放,拖动) [实例截图] [核心代码] ImageDemo-2014-02-18 └── ImageDemo-2014-02-18 ├ ...

  6. 安卓开发仿微信图片拖拽_Android 仿微信朋友圈发表图片拖拽和删除功能

    朋友圈实现原理 我们使用 Android Device Monitor 来分析朋友圈发布图片的界面实现原理.如果需要分析其他应用的界面实现也是采用这种方法哦. 打开 Android Device Mo ...

  7. 安卓开发仿微信图片拖拽_Android 仿微信朋友圈图片拖拽返回

    目前的app的动画效果是越来越炫了,很多主流app的图片预览返回都有类似功能,比较常见的是ios自带相册,微信朋友圈等等.自己项目中也有类似功能,最近整理了一下这个功能的代码,做个笔记记录,有兴趣的朋 ...

  8. 基于微信小程序开发的仿微信demo

    (本文参考自github/liujians,地址:https://github.com/liujians/weApp) 作者声明: 基于微信小程序开发的仿微信demo  整合了ionic的样式库和we ...

  9. android 辐射动画_Android仿微信雷达辐射搜索好友(逻辑清晰实现简单)

    不知不觉这个春节也已经过完了,遗憾家里没网,没能及时给大家送上祝福,今天回到深圳,明天就要上班了,小伙伴们是不是和我一样呢?今天讲的是一个大家都见过的动画,雷达搜索好友嘛,原理也十分的简单,你看完我的 ...

最新文章

  1. 这个勒索软件也太菜了!
  2. 大学python用什么教材-数据结构 Python语言描述 大学教材
  3. 如何通过示例使用Java中的Exchanger
  4. emlog博客主题价值358元lu1.3模板
  5. centos samba 看不到共享目录_samba共享服务
  6. 西门子ug通用后处理_五轴UG(NX)后处理
  7. ubuntu8.10_深圳源
  8. STL之set的应用
  9. 视频不显示的分析方法
  10. matlab拟合二元方程,MATLAB拟合方程1
  11. 分享一些使用电脑的小技巧
  12. 找到Linux共享文件夹的实际位置
  13. 在windows7下给vs2015配置dirent.h头文件
  14. 台式计算机 无线接收,台式电脑无线接收器插上连不上网怎么处理
  15. 辅音字母组合功能音中的浊化现象
  16. 温习Java和基础汇总
  17. 一加和华为买哪个好 一加9用新特性赢得消费者口碑
  18. 淘宝 模拟 登录 总结 【QQ 346767073 】
  19. 计算机毕业设计springboot+vue基本微信小程序的校园二手闲置物品交易小程序 uniapp
  20. Android实验报告

热门文章

  1. 火影忍者246集视频VW
  2. jquerymobile创建9宫格事例
  3. SEO人员,该如何打造具有搜索属性的内容?
  4. 打小都说我聪明,自从学了Linux,我才如梦初醒
  5. flink1.13 upsert-kafka connector 实时报表 视频演示
  6. react中副作用函数(useEffect)详解
  7. 重磅 | Stratifyd入选“数据分析与商业智能平台典型供应商”
  8. BGP的通告和选路规则
  9. Python中英文翻译工具
  10. 少年你骨骼精奇?AI现在可以帮你看一看了