当前位置: 移动技术网 > IT编程>移动开发>Android > Android仿微信多人音视频通话界面

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

2019年09月06日  | 移动技术网IT编程  | 我要评论

抚顺小姐,随州供求世界,礼泉县人民政府

工作中需要实现一个类似微信多人视频通话功能的界面,分别使用自定义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
 }
}

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网