Android仿微信视频聊天本地与远程切换功能

2024-03-22 09:52

本文主要是介绍Android仿微信视频聊天本地与远程切换功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、xml布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/coordinatorLayout"android:layout_width="@dimen/dp_640"android:layout_height="@dimen/dp_400"android:background="@color/pageBgColor"android:orientation="vertical"><!--  视频预览 --><csu.xiaoya.robotApp.ui.activity.homepage.familydct.bean.DraggableTextureViewandroid:id="@+id/preview"android:layout_width="@dimen/dp_640"android:layout_height="@dimen/dp_400"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintLeft_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /><!--  远程视频 --><csu.xiaoya.robotApp.ui.activity.homepage.familydct.bean.DraggableTextureViewandroid:id="@+id/remoteUserView"android:layout_width="150dp"android:layout_height="180dp"android:layout_marginTop="30dp"android:layout_marginRight="30dp"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintLeft_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /><ImageViewandroid:id="@+id/imHead"android:layout_width="@dimen/dp_120"android:layout_height="@dimen/dp_120"android:layout_gravity="center"android:layout_marginBottom="@dimen/dp_100"android:scaleType="centerCrop"android:src="@mipmap/doctor_head"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><ImageViewandroid:id="@+id/changeVideoWindows"android:layout_width="@dimen/dp_30"android:layout_height="@dimen/dp_30"android:layout_marginLeft="@dimen/dp_30"android:layout_marginTop="@dimen/dp_30"android:background="@drawable/change_windows"android:src="@mipmap/video_windows_change"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

  二、切换代码

 /*** 通话大小* 窗口切换*/private boolean isLocalVideoSmallState = true;private void switchWindowMode(VideoChatDialog videoChatDialog, boolean isLocalVideoSmall) {ConstraintLayout constraintLayout = videoChatDialog.findViewById(R.id.coordinatorLayout);TextureView localVideoTextureView = videoChatDialog.findViewById(R.id.preview);TextureView remoteVideoTextureView = videoChatDialog.findViewById(R.id.remoteUserView);ImageView changeVideoWindows = videoChatDialog.findViewById(R.id.changeVideoWindows);ConstraintSet constraintSet = new ConstraintSet();constraintSet.clone(constraintLayout);if (isLocalVideoSmall) {constraintLayout.removeView(localVideoTextureView);constraintLayout.removeView(remoteVideoTextureView);constraintLayout.removeView(changeVideoWindows);constraintLayout.addView(remoteVideoTextureView);constraintLayout.addView(localVideoTextureView);constraintLayout.addView(changeVideoWindows);// 远程端全屏模式remoteVideoTextureView.setEnabled(false);constraintSet.clear(remoteVideoTextureView.getId());constraintSet.connect(remoteVideoTextureView.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 0);constraintSet.connect(remoteVideoTextureView.getId(), ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, 0);constraintSet.connect(remoteVideoTextureView.getId(), ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, 0);constraintSet.constrainWidth(remoteVideoTextureView.getId(), 1280);constraintSet.constrainHeight(remoteVideoTextureView.getId(), 800);// 本地小窗口localVideoTextureView.setEnabled(true);constraintSet.clear(localVideoTextureView.getId());constraintSet.connect(localVideoTextureView.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 30);constraintSet.connect(localVideoTextureView.getId(), ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, 0);constraintSet.connect(localVideoTextureView.getId(), ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, 30);constraintSet.constrainWidth(localVideoTextureView.getId(), 300); // 设置小窗口的宽度constraintSet.constrainHeight(localVideoTextureView.getId(), 200);isLocalVideoSmallState = false;} else {constraintLayout.removeView(remoteVideoTextureView);constraintLayout.removeView(localVideoTextureView);constraintLayout.removeView(changeVideoWindows);constraintLayout.addView(localVideoTextureView);constraintLayout.addView(remoteVideoTextureView);constraintLayout.addView(changeVideoWindows);// 本地 全屏模式localVideoTextureView.setEnabled(false);constraintSet.clear(localVideoTextureView.getId());constraintSet.connect(localVideoTextureView.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 0);constraintSet.connect(localVideoTextureView.getId(), ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, 0);constraintSet.connect(localVideoTextureView.getId(), ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, 0);constraintSet.constrainWidth(localVideoTextureView.getId(), 1280);constraintSet.constrainHeight(localVideoTextureView.getId(), 800);// 远程 小窗口remoteVideoTextureView.setEnabled(true);constraintSet.clear(remoteVideoTextureView.getId());constraintSet.connect(remoteVideoTextureView.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 30);constraintSet.connect(remoteVideoTextureView.getId(), ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, 0);constraintSet.connect(remoteVideoTextureView.getId(), ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, 30);constraintSet.constrainWidth(remoteVideoTextureView.getId(), 300); // 设置小窗口的宽度constraintSet.constrainHeight(remoteVideoTextureView.getId(), 200);isLocalVideoSmallState = true;}constraintSet.applyTo(constraintLayout);}

三、自定义可拖拽TextureView 

/*** 自定义可拖动* TextureView*/public class DraggableTextureView extends TextureView {private float lastX;private float lastY;private boolean isDragging;public DraggableTextureView(Context context) {super(context);init();}public DraggableTextureView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);init();}public DraggableTextureView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:lastX = event.getRawX();lastY = event.getRawY();isDragging = true;break;case MotionEvent.ACTION_MOVE:if (isDragging) {float dx = event.getRawX() - lastX;float dy = event.getRawY() - lastY;int newLeft = (int) (v.getLeft() + dx);int newTop = (int) (v.getTop() + dy);int newRight = (int) (v.getRight() + dx);int newBottom = (int) (v.getBottom() + dy);v.layout(newLeft, newTop, newRight, newBottom);lastX = event.getRawX();lastY = event.getRawY();}break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:isDragging = false;break;}return true;}});}}

这篇关于Android仿微信视频聊天本地与远程切换功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/835068

相关文章

Python+FFmpeg实现视频自动化处理的完整指南

《Python+FFmpeg实现视频自动化处理的完整指南》本文总结了一套在Python中使用subprocess.run调用FFmpeg进行视频自动化处理的解决方案,涵盖了跨平台硬件加速、中间素材处理... 目录一、 跨平台硬件加速:统一接口设计1. 核心映射逻辑2. python 实现代码二、 中间素材处

Android使用java实现网络连通性检查详解

《Android使用java实现网络连通性检查详解》这篇文章主要为大家详细介绍了Android使用java实现网络连通性检查的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录NetCheck.Java(可直接拷贝)使用示例(Activity/Fragment 内)权限要求

python项目环境切换的几种实现方式

《python项目环境切换的几种实现方式》本文主要介绍了python项目环境切换的几种实现方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 如何在不同python项目中,安装不同的依赖2. 如何切换到不同项目的工作空间3.创建项目

SpringBoot+Vue3整合SSE实现实时消息推送功能

《SpringBoot+Vue3整合SSE实现实时消息推送功能》在日常开发中,我们经常需要实现实时消息推送的功能,这篇文章将基于SpringBoot和Vue3来简单实现一个入门级的例子,下面小编就和大... 目录前言先大概介绍下SSE后端实现(SpringBoot)前端实现(vue3)1. 数据类型定义2.

SpringBoot整合Apache Spark实现一个简单的数据分析功能

《SpringBoot整合ApacheSpark实现一个简单的数据分析功能》ApacheSpark是一个开源的大数据处理框架,它提供了丰富的功能和API,用于分布式数据处理、数据分析和机器学习等任务... 目录第一步、添加android依赖第二步、编写配置类第三步、编写控制类启动项目并测试总结ApacheS

2025最新版Android Studio安装及组件配置教程(SDK、JDK、Gradle)

《2025最新版AndroidStudio安装及组件配置教程(SDK、JDK、Gradle)》:本文主要介绍2025最新版AndroidStudio安装及组件配置(SDK、JDK、Gradle... 目录原生 android 简介Android Studio必备组件一、Android Studio安装二、A

Python实现繁体转简体功能的三种方案

《Python实现繁体转简体功能的三种方案》在中文信息处理中,繁体字与简体字的转换是一个常见需求,无论是处理港澳台地区的文本数据,还是开发面向不同中文用户群体的应用,繁简转换都是不可或缺的功能,本文将... 目录前言为什么需要繁简转换?python实现方案方案一:使用opencc库方案二:使用zhconv库

Qt实现删除布局与布局切换功能

《Qt实现删除布局与布局切换功能》在Qt应用开发中,动态管理布局是一个常见需求,比如根据用户操作动态删除某个布局,或在不同布局间进行切换,本文将详细介绍如何实现这些功能,并通过完整示例展示具体操作,需... 目录一、Qt动态删除布局1. 布局删除的注意事项2. 动态删除布局的实现步骤示例:删除vboxLay

Spring Boot整合Redis注解实现增删改查功能(Redis注解使用)

《SpringBoot整合Redis注解实现增删改查功能(Redis注解使用)》文章介绍了如何使用SpringBoot整合Redis注解实现增删改查功能,包括配置、实体类、Repository、Se... 目录配置Redis连接定义实体类创建Repository接口增删改查操作示例插入数据查询数据删除数据更

Nginx搭建前端本地预览环境的完整步骤教学

《Nginx搭建前端本地预览环境的完整步骤教学》这篇文章主要为大家详细介绍了Nginx搭建前端本地预览环境的完整步骤教学,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录项目目录结构核心配置文件:nginx.conf脚本化操作:nginx.shnpm 脚本集成总结:对前端的意义很多