基于cameraX补充全屏/缩放功能

发布时间:2026/7/24 11:36:20
基于cameraX补充全屏/缩放功能 一、 核心代码补充// 当前全屏的是哪个null 表示两个都是半屏 private PreviewView currentFullScreen null;private void setupClickListeners() { previewView1.setOnClickListener(v - { toggleFullScreen(previewView1); }); previewView2.setOnClickListener(v - { toggleFullScreen(previewView2); }); }/** * 切换逻辑 * - 点击的是当前全屏 → 恢复两个半屏 * - 点击的是另一个 → 点击的全屏另一个隐藏 */ private void toggleFullScreen(PreviewView clickedView) { PreviewView otherView (clickedView previewView1) ? previewView2 : previewView1; if (currentFullScreen clickedView) { // 恢复双半屏 setWeight(clickedView, 1f); setWeight(otherView, 1f); otherView.setVisibility(View.VISIBLE); currentFullScreen null; } else { // 点击的全屏另一个隐藏 setWeight(clickedView, 100f); setWeight(otherView, 0f); otherView.setVisibility(View.INVISIBLE); currentFullScreen clickedView; } } private void setWeight(View view, float weight) { LinearLayout.LayoutParams params (LinearLayout.LayoutParams) view.getLayoutParams(); params.weight weight; view.setLayoutParams(params); }二、全部源码public class MultiCameraActivity extends AppCompatActivity { private PreviewView previewView1, previewView2; // 当前全屏的是哪个null 表示两个都是半屏 private PreviewView currentFullScreen null; // 1. 【最新权限写法】使用 ActivityResultLauncher 替代老旧的 onRequestPermissionsResult private final ActivityResultLauncherString requestPermissionLauncher registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted - { if (isGranted) { startCameraPreview(); } else { Toast.makeText(this, 未授予相机权限无法使用预览功能, Toast.LENGTH_SHORT).show(); Intent intent new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.parse(package: getPackageName())); startActivity(intent); finish(); } }); Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_camera); previewView1 findViewById(R.id.previewView1); previewView2 findViewById(R.id.previewView2); // 2. 检查权限状态 if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) PackageManager.PERMISSION_GRANTED) { startCameraPreview(); } else { requestPermissionLauncher.launch(Manifest.permission.CAMERA); } } private void startCameraPreview() { ListenableFutureProcessCameraProvider cameraProviderFuture ProcessCameraProvider.getInstance(this); // 【防卡顿优化】使用 addListener 异步获取避免 .get() 阻塞主线程 cameraProviderFuture.addListener(() - { try { ProcessCameraProvider cameraProvider cameraProviderFuture.get(); cameraProvider.unbindAll(); // 清理旧状态 // 1. 构建后置摄像头预览 Preview previewBack new Preview.Builder() .build(); previewBack.setSurfaceProvider(previewView1.getSurfaceProvider()); // 2. 构建前置摄像头预览 Preview previewFront new Preview.Builder() .build(); previewFront.setSurfaceProvider(previewView2.getSurfaceProvider()); // 3. 分别绑定前后摄像头 cameraProvider.bindToLifecycle( this, CameraSelector.DEFAULT_BACK_CAMERA, // 后置 previewBack ); cameraProvider.bindToLifecycle( this,CameraSelector.DEFAULT_FRONT_CAMERA, // 前置 previewFront ); Toast.makeText(this, 双摄预览启动成功, Toast.LENGTH_SHORT).show(); setupClickListeners(); } catch (Exception e) { // 如果设备硬件不支持双摄并发会在这里捕获异常 Toast.makeText(this, 启动失败(可能硬件不支持双摄): e.getMessage(), Toast.LENGTH_SHORT).show(); } }, ContextCompat.getMainExecutor(this)); } private void setupClickListeners() { previewView1.setOnClickListener(v - { toggleFullScreen(previewView1); }); previewView2.setOnClickListener(v - { toggleFullScreen(previewView2); }); } /** * 切换逻辑 * - 点击的是当前全屏 → 恢复两个半屏 * - 点击的是另一个 → 点击的全屏另一个隐藏 */ private void toggleFullScreen(PreviewView clickedView) { PreviewView otherView (clickedView previewView1) ? previewView2 : previewView1; if (currentFullScreen clickedView) { // 恢复双半屏 setWeight(clickedView, 1f); setWeight(otherView, 1f); otherView.setVisibility(View.VISIBLE); currentFullScreen null; } else { // 点击的全屏另一个隐藏 setWeight(clickedView, 100f); setWeight(otherView, 0f); otherView.setVisibility(View.INVISIBLE); currentFullScreen clickedView; } } private void setWeight(View view, float weight) { LinearLayout.LayoutParams params (LinearLayout.LayoutParams) view.getLayoutParams(); params.weight weight; view.setLayoutParams(params); } }