unbindAll

本文介绍了一种通过替换DOM元素来解除所有绑定事件的方法。该方法适用于需要彻底清除元素上所有事件监听器的场景。

 

     函数设计场景

 

           给指定元素解除所有绑定的事件监听

 

    代码部分

 

/*
 * @name unbindAll  删除指定元素的所有绑定事件
 * @param {HTMLElement} elem
*/
function unbindAll(elem){
       //复制一个新的节点
       var new_elem = elem.cloneNode(true);
       
       //新元素替换旧元素
       elem.parentNode.replaceChild(new_elem,elem);
}

 

 

   扩展阅读:

 

   http://stackoverflow.com/questions/9251837/how-to-remove-all-listeners-in-an-element

 

package com.example.test2; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.camera.core.Camera; import androidx.camera.core.CameraSelector; import androidx.camera.core.ImageCapture; import androidx.camera.core.ImageCaptureException; import androidx.camera.core.Preview; import androidx.camera.lifecycle.ProcessCameraProvider; import androidx.camera.video.FileOutputOptions; import androidx.camera.video.Quality; import androidx.camera.video.QualitySelector; import androidx.camera.video.Recorder; import androidx.camera.video.Recording; import androidx.camera.video.VideoCapture; import androidx.camera.video.VideoRecordEvent; import androidx.camera.view.PreviewView; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.Manifest; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.Toast; import android.widget.VideoView; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.ui.StyledPlayerView; import com.google.common.util.concurrent.ListenableFuture; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class MainActivity extends AppCompatActivity { private static final String TAG = "CameraXDemo"; private static final int REQUEST_CAMERA_PERMISSION = 1001; private PreviewView previewView; private FrameLayout previewContainer; private Button toggleCameraButton; private Button openCameraButton; private Button openViewButton; private ImageView imageView; private StyledPlayerView playerView; private ExoPlayer player; private LinearLayout mediaDisplayLayout; // 新增的媒体显示区域布局 private ListenableFuture<ProcessCameraProvider> cameraProviderFuture; private ProcessCameraProvider cameraProvider; private boolean isCameraRunning = false; private boolean isRecording = false; private Camera camera; private ImageCapture imageCapture; private VideoCapture<Recorder> videoCapture; private Recording recording; private ExecutorService cameraExecutor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); previewView = findViewById(R.id.previewView); previewContainer = findViewById(R.id.previewContainer); toggleCameraButton = findViewById(R.id.toggleCameraButton); openCameraButton = findViewById(R.id.openCameraButton); openViewButton = findViewById(R.id.openViewButton); imageView = findViewById(R.id.image); mediaDisplayLayout = findViewById(R.id.mediaDisplayLayout); // 获取媒体显示区域布局 // 初始化视频播放器视图 playerView = new StyledPlayerView(this); playerView.setLayoutParams(new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); mediaDisplayLayout.addView(playerView); // 添加到媒体显示区域 playerView.setVisibility(View.GONE); // 初始化ExoPlayer player = new ExoPlayer.Builder(this).build(); playerView.setPlayer(player); // 初始化相机执行器 cameraExecutor = Executors.newSingleThreadExecutor(); // 初始化 CameraProvider cameraProviderFuture = ProcessCameraProvider.getInstance(this); // 打开/关闭摄像头按钮 toggleCameraButton.setOnClickListener(v -> { if (isCameraRunning) { stopCamera(); } else { if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}, REQUEST_CAMERA_PERMISSION); } else { startCamera(); } } }); // 拍照按钮 openCameraButton.setOnClickListener(v -> { if (isCameraRunning && !isRecording) { takePhoto(); } else if (isRecording) { Toast.makeText(this, "请先停止录像", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "请先打开摄像头", Toast.LENGTH_SHORT).show(); } }); // 录像按钮 openViewButton.setOnClickListener(v -> { if (isCameraRunning) { if (isRecording) { stopRecording(); } else { startRecording(); } } else { Toast.makeText(this, "请先打开摄像头", Toast.LENGTH_SHORT).show(); } }); cameraProviderFuture.addListener(() -> { try { cameraProvider = cameraProviderFuture.get(); Log.d(TAG, "CameraProvider 初始化成功"); } catch (ExecutionException | InterruptedException e) { Log.e(TAG, "CameraProvider 初始化失败", e); } }, ContextCompat.getMainExecutor(this)); } private void startCamera() { if (cameraProvider == null) { Log.e(TAG, "CameraProvider 未初始化"); return; } // 确保预览视图可见 previewView.setVisibility(View.VISIBLE); previewContainer.setBackgroundColor(Color.WHITE); // 创建Preview用例 Preview preview = new Preview.Builder().build(); preview.setSurfaceProvider(previewView.getSurfaceProvider()); // 创建ImageCapture用例 imageCapture = new ImageCapture.Builder() .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY) .build(); // 创建VideoCapture用例 Recorder recorder = new Recorder.Builder() .setQualitySelector(QualitySelector.from(Quality.HIGHEST)) .build(); videoCapture = VideoCapture.withOutput(recorder); CameraSelector cameraSelector = new CameraSelector.Builder() .requireLensFacing(CameraSelector.LENS_FACING_BACK) .build(); try { // 解绑所有用例 cameraProvider.unbindAll(); // 绑定生命周期和用例 camera = cameraProvider.bindToLifecycle( this, cameraSelector, preview, imageCapture, videoCapture); Log.d(TAG, "相机绑定成功"); // 显示PreviewView previewContainer.setVisibility(View.VISIBLE); imageView.setVisibility(View.GONE); toggleCameraButton.setText("关闭摄像头"); isCameraRunning = true; } catch (Exception e) { Log.e(TAG, "绑定失败", e); Toast.makeText(this, "相机绑定失败", Toast.LENGTH_SHORT).show(); } } private void stopCamera() { if (isRecording) { stopRecording(); } if (cameraProvider != null) { cameraProvider.unbindAll(); camera = null; imageCapture = null; videoCapture = null; // 预览区域变为黑色 previewContainer.setVisibility(View.VISIBLE); previewView.setVisibility(View.INVISIBLE); previewContainer.setBackgroundColor(Color.BLACK); toggleCameraButton.setText("打开摄像头"); isCameraRunning = false; Log.d(TAG, "相机已关闭"); } } private void takePhoto() { if (imageCapture == null) { return; } File photoFile = createImageFile(); if (photoFile == null) { Toast.makeText(this, "创建照片文件失败", Toast.LENGTH_SHORT).show(); return; } ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(photoFile).build(); imageCapture.takePicture( outputFileOptions, ContextCompat.getMainExecutor(this), new ImageCapture.OnImageSavedCallback() { @Override public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) { String savedPath = photoFile.getAbsolutePath(); Log.d(TAG, "照片保存成功: " + savedPath); runOnUiThread(() -> { playerView.setVisibility(View.GONE); imageView.setVisibility(View.VISIBLE); Bitmap bitmap = BitmapFactory.decodeFile(savedPath); imageView.setImageBitmap(bitmap); Toast.makeText(MainActivity.this, "拍照成功", Toast.LENGTH_SHORT).show(); }); } @Override public void onError(@NonNull ImageCaptureException exception) { Log.e(TAG, "拍照失败: " + exception.getMessage(), exception); runOnUiThread(() -> { Toast.makeText(MainActivity.this, "拍照失败: " + exception.getMessage(), Toast.LENGTH_SHORT).show(); }); } }); } private void startRecording() { if (videoCapture == null || isRecording) { return; } File videoFile = createVideoFile(); if (videoFile == null) { Toast.makeText(this, "创建视频文件失败", Toast.LENGTH_SHORT).show(); return; } FileOutputOptions fileOutputOptions = new FileOutputOptions.Builder(videoFile).build(); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, REQUEST_CAMERA_PERMISSION); return; } recording = videoCapture.getOutput() .prepareRecording(this, fileOutputOptions) .withAudioEnabled() .start(ContextCompat.getMainExecutor(this), event -> { if (event instanceof VideoRecordEvent.Start) { runOnUiThread(() -> { isRecording = true; openViewButton.setText("停止录制"); Toast.makeText(this, "开始录制", Toast.LENGTH_SHORT).show(); }); } else if (event instanceof VideoRecordEvent.Finalize) { if (!((VideoRecordEvent.Finalize) event).hasError()) { String savedPath = videoFile.getAbsolutePath(); Log.d(TAG, "视频保存成功: " + savedPath); runOnUiThread(() -> { setupVideoPlayer(Uri.fromFile(videoFile)); }); } else { Log.e(TAG, "视频录制出错: " + ((VideoRecordEvent.Finalize) event).getError()); } runOnUiThread(() -> { isRecording = false; openViewButton.setText("开始录制"); }); } }); } private void stopRecording() { if (recording != null) { recording.stop(); recording = null; } } private void setupVideoPlayer(Uri videoUri) { imageView.setVisibility(View.GONE); playerView.setVisibility(View.VISIBLE); player.setMediaItem(MediaItem.fromUri(videoUri)); player.prepare(); player.setPlayWhenReady(false); playerView.setOnClickListener(v -> { if (player.isPlaying()) { player.pause(); } else { player.setPlayWhenReady(true); player.seekTo(0); } }); } private File createImageFile() { String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES); try { return File.createTempFile( imageFileName, ".jpg", storageDir); } catch (IOException e) { Log.e(TAG, "创建照片文件失败", e); return null; } } private File createVideoFile() { String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); String videoFileName = "VIDEO_" + timeStamp + "_"; File storageDir = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES); try { return File.createTempFile( videoFileName, ".mp4", storageDir); } catch (IOException e) { Log.e(TAG, "创建视频文件失败", e); return null; } } @Override protected void onDestroy() { super.onDestroy(); cameraExecutor.shutdown(); if (cameraProvider != null) { cameraProvider.unbindAll(); cameraProvider.shutdown(); } if (player != null) { player.release(); } } }在此基础上增加一个删除按钮,用于删除照片和视频
07-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值