Handler、SurfaceHolder

一、何时需要使用安卓线程Handler、SurfaceHolder
在安卓中主界面activity就是一个线程,在使用线程的图像需要改变主线程界面时,需要通过Handler或SurfaceHolder传递改变的图像


二、Handler的使用
1.定义MyHandler继承Handler类,并且重写handleMessage(Message msg)方法。在方法体内对改变的图像进行操作,别忘了操作后imageview.setImageBitmap(bitmap);   // 用缓冲画在图片上
2.在线程的run()方法中创建Message对象,并将改变的值传入Message对象,并用Handler的sendMessage(Message m)方法发送给处理器


三、SurfaceHolder的使用
    在使用SurfaceHolder前,需要了解什么是回调。
android中预先写好的函数,在使用的时候调用,监听器也是一种回调,在触发事件源时启动,在Callback接口中预定义了三个方法,分别以对应不同状态,在不同状态是调用(纯个人理解,欢迎交流)
1.在布局文件中的画布改为SurfaceView
2. SurfaceView sf = (SurfaceView)this.findViewById(R.id.imageView1); //获取SurfaceView对象
3. SurfaceHolder sfh = sf.getHolder();      //你用SurfaceView对象获得SurfaceHolder对象
4. sfh.addCallback(new MyCallback(sfh));   // 加入回调方法
5. 定义类MyCallback实现Callback接口,在surfaceCreated(SurfaceHolder holder)方法中启动线程
6. 在线程run方法中改变图像的参数值,使之变化。
            canvas = sfh.lockCanvas();              // 锁定画布
   canvas.drawCircle(x++, y++, 10, mpaint);//改变图像
           sfh.unlockCanvasAndPost(canvas);       //解锁画布,将改变的值画在SurfaceView上


四、Handler、SurfaceHolder的区别
Handler:View绘制工作都交给主线程执行
SurfaceHolder:SurfaceView中通过另外一个线程对界面进行绘制
在一般的绘制使用Handler、SurfaceHolder没有太大区别,在游戏界面中对界面进行实时改变的可用SurfaceHolder提高流畅度

修改主页面 qr_bt.setOnClickListener(view ->{ ScanOptions options = new ScanOptions(); options.setDesiredBarcodeFormats(ScanOptions.QR_CODE); // 只扫描二维码 options.setPrompt("将二维码放入框内"); // 提示信息 options.setCameraId(0); // 使用后置摄像头 options.setBeepEnabled(true); // 扫描成功时播放声音 options.setBarcodeImageEnabled(true); // 保存扫描的图片 options.setOrientationLocked(true); // 锁定方向 options.setCaptureActivity(ScanActivity.class);// 强制竖屏 scanLauncher.launch(options); //启动扫描 }); 以及 @SuppressLint("MissingPermission") final ActivityResultLauncher<ScanOptions> scanLauncher = registerForActivityResult(new ScanContract(), result -> { if (result.getContents() != null) { // 扫描成功,获取结果 String scanResult = result.getContents(); BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); BluetoothDevice device = adapter.getRemoteDevice( scanResult); //跳转页面 Intent intent = new Intent(this,DataActivity.class); intent.putExtra("device",device); startActivity(intent); if (bluetoothGatt != null) { bluetoothGatt.disconnect(); bluetoothGatt.close(); // 关键:释放资源 bluetoothGatt = null; // 置空避免重复使用 } bluetoothGatt = device.connectGatt(this, false, new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { switch (newState) { case BluetoothProfile.STATE_CONNECTED://连接成功 isConnected = true; Log.d(TAG, "连接成功"); runOnUiThread(() -> { // layConnectingLoading.setVisibility(View.GONE); showMsg("连接成功"); }); break; case BluetoothProfile.STATE_DISCONNECTED://断开连接 isConnected = false; Log.d(TAG, "断开连接"); runOnUiThread(() -> { // layConnectingLoading.setVisibility(View.GONE); showMsg("断开连接"); }); break; default: break; } } }); //Toast.makeText(LoginActivity.this, "扫描结果: " + scanResult, Toast.LENGTH_LONG).show(); // 这里可以处理扫描结果,比如显示在界面上或者发送到服务器等 } });将扫描页面public class ScanActivity extends Activity implements SurfaceHolder.Callback { private CameraManager cameraManager; private ScanningQRCodeHandler handler; private ViewfinderView viewfinderView; private boolean hasSurface; private Collection<BarcodeFormat> decodeFormats; private String characterSet; //管理震动和声音 private BeepManager beepManager; //界面亮度 private AmbientLightManager ambientLightManager; private SurfaceView surfaceView; private SurfaceHolder surfaceHolder; private ImageView ivFlash; private ImageView ivImage; public static final int RC_CHOOSE_PHOTO = 2000; //相册返回过来的图片转成bitmap在专程数组 private byte[] datas; public static final String FULL_SCANNING = "FULL_SCANNING"; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //常亮屏 Window window = getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setContentView(R.layout.activity_scan); viewfinderView = findViewById(R.id.viewfinder_view); surfaceView = findViewById(R.id.preview_view); ivFlash = findViewById(R.id.iv_flash); int flag =getIntent().getIntExtra(FULL_SCANNING,0); CameraConfigurationUtils.setFullScanning(flag>0); ivImage = findViewById(R.id.iv_image); findViewById(R.id.iv_close).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { setResult(RESULT_CANCELED); finish(); } }); hasSurface = false; beepManager = new BeepManager(this, true); ambientLightManager = new AmbientLightManager(this); cameraManager = new CameraManager(getApplication()); viewfinderView.setCameraManager(cameraManager); surfaceHolder = surfaceView.getHolder(); ivFlash.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (cameraManager.getTorchState()) { cameraManager.setTorch(false); } else { cameraManager.setTorch(true); } ivFlash.setImageResource(cameraManager.getTorchState() ? R.drawable.ic_baseline_flash_off_24 : R.drawable.ic_baseline_flash_on_24); } }); ivImage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intentToPickPic = new Intent(Intent.ACTION_PICK, null); intentToPickPic.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); startActivityForResult(intentToPickPic, RC_CHOOSE_PHOTO); } }); } @Override protected void onResume() { super.onResume(); // CameraManager must be initialized here, not in onCreate(). This is necessary because we don't // want to open the camera driver and measure the screen size if we're going to show the help on // first launch. That led to bugs where the scanning rectangle was the wrong size and partially // off screen. handler = null; beepManager.updatePrefs(); ambientLightManager.start(cameraManager); decodeFormats = null; characterSet = null; if (hasSurface) { // The activity was paused but not stopped, so the surface still exists. Therefore // surfaceCreated() won't be called, so init the camera here. initCamera(surfaceHolder); } else { // Install the callback and wait for surfaceCreated() to init the camera. surfaceHolder.addCallback(this); } } @Override protected void onPause() { if (handler != null) { handler.quitSynchronously(); handler = null; } ambientLightManager.stop(); beepManager.close(); cameraManager.closeDriver(); //historyManager = null; // Keep for onActivityResult if (!hasSurface) { surfaceHolder.removeCallback(this); } super.onPause(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_BACK: setResult(RESULT_CANCELED); finish(); break; default: break; } return super.onKeyDown(keyCode, event); } @Override public void surfaceCreated(SurfaceHolder holder) { if (!hasSurface) { hasSurface = true; initCamera(holder); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { hasSurface = false; } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // do nothing } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RC_CHOOSE_PHOTO && resultCode == Activity.RESULT_OK) { Uri uri = data.getData(); Bitmap bmp = null; try { bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri)); } catch (FileNotFoundException e) { e.printStackTrace(); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos); datas = baos.toByteArray(); //这里没有直接去发送消息 在onPause的时候handler已经退出工作了需要在onResume重新赋值才能发送所以在initCamera中去发送了 } } /** * 解码完成 */ public void handleDecode(Result rawResult, Bitmap barcode, float scaleFactor) { boolean fromLiveScan = barcode != null; if (fromLiveScan) { // 声音和震动 beepManager.playBeepSoundAndVibrate(); } Intent intent = new Intent(); intent.putExtra("resultText", rawResult.getText()); Message message = Message.obtain(handler, R.id.return_scan_result, intent); handler.sendMessage(message); } private void initCamera(SurfaceHolder surfaceHolder) { if (surfaceHolder == null) { throw new IllegalStateException("No SurfaceHolder provided"); } if (cameraManager.isOpen()) { return; } try { cameraManager.openDriver(surfaceHolder); ivFlash.setImageResource(cameraManager.getTorchState() ? R.drawable.ic_baseline_flash_off_24 : R.drawable.ic_baseline_flash_on_24); // Creating the handler starts the preview, which can also throw a RuntimeException. if (handler == null) { handler = new ScanningQRCodeHandler(Looper.myLooper(), this, decodeFormats, null, characterSet, cameraManager); if (datas != null) { Message message = Message.obtain(handler, R.id.decode_image, datas); handler.sendMessage(message); } } } catch (IOException ioe) { displayFrameworkBugMessageAndExit(); } catch (RuntimeException e) { displayFrameworkBugMessageAndExit(); } } public void decodeImageFailed() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(getString(R.string.app_name)); builder.setMessage("未发现二维码"); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { } }); builder.show(); } private void displayFrameworkBugMessageAndExit() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(getString(R.string.app_name)); builder.setMessage("很遗憾,Android 相机出现问题。你可能需要重启设备"); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { } }); builder.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialogInterface) { } }); builder.show(); } public ViewfinderView getViewfinderView() { return viewfinderView; } public Handler getHandler() { return handler; } public CameraManager getCameraManager() { return cameraManager; } private double cropWight = -1; private double cropHeight = -1; }扫描结果返回到主页面,并完成蓝牙连接
最新发布
12-05
给以下代码注释:package com.example.readvideo; import static com.example.readvideo.MainActivity.context; import android.annotation.SuppressLint; import android.app.Activity; import android.content.pm.ActivityInfo; import android.content.res.AssetFileDescriptor; import android.graphics.Color; import android.graphics.PixelFormat; import android.media.MediaMetadataRetriever; import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.DisplayMetrics; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.SeekBar; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.constraintlayout.widget.ConstraintLayout; import java.io.File; import java.io.IOException; import java.net.URI; import java.text.SimpleDateFormat; import java.util.ArrayList; public class VideoActivity extends Activity { private SurfaceView surfaceView; private MediaPlayer mediaPlayer=new MediaPlayer(); private SeekBar vseekBar; private TextView vtitle,vgress,vtotal; private ImageView vplay,vpause,vback,vfastback ,vfastforword,vlast,vnext,vinfor; private RelativeLayout relativeLayout1,relativeLayout2; private View infoView; private TextView nameTv; private TextView createTv; private TextView sizeTv; private TextView formatTv; private TextView resolutionTv; private TextView pathTv; public WindowManager windowManager; public SurfaceHolder surfaceHolder; private boolean isInfoDialogShow=true; private static String vPath; private File vFile; private int nowtime,total; private static int fileIndex; private ArrayList<DataValue> videolist=new ArrayList<>(); DataProvider dataProvider; private boolean switchlist; Handler handler=new Handler(new Handler.Callback() { //这里创建Handler的方式是不想实现子类方法,直接引用callback接口来完成Handler的实例化 @Override public boolean handleMessage(@NonNull Message msg) { //处理线程中的message,what是线程中用户定义的消息代码,以便收件人可以根据识别 if(msg.what==1){ //若是1的消息传入 try { nowtime=mediaPlayer.getCurrentPosition(); vgress.setText(Tool.millisToStringShort(nowtime)); vseekBar.setProgress(nowtime); handler.sendEmptyMessageDelayed(1,10); //设置一秒延迟再发送消息 }catch (IllegalStateException e){ e.printStackTrace(); } } return false; } }); //总结就是播放的开始发送一个id为1的空消息,然后将该消息移除并更新进度,然后接下来每1秒更新一次消息,也就是更新已播放秒数s1的数值 @SuppressLint("MissingInflatedId") protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.video_view); init(); initInfoView(); } @SuppressLint("WrongViewCast") private void init(){ surfaceView=findViewById(R.id.sfview); vseekBar=findViewById(R.id.videosb); vtitle=findViewById(R.id.videotitle); vplay=findViewById(R.id.videoplay); vpause=findViewById(R.id.videopause); vback=findViewById(R.id.videoback); vgress=findViewById(R.id.videogress); vtotal=findViewById(R.id.videototal); vfastback=findViewById(R.id.videofastback); vfastforword=findViewById(R.id.videofastforward); vlast=findViewById(R.id.videolast); vnext=findViewById(R.id.videonext); vinfor=findViewById(R.id.videoinfor); relativeLayout1=findViewById(R.id.videorl1); relativeLayout2=findViewById(R.id.videorl2); vplay.setOnClickListener(onClickListener); vpause.setOnClickListener(onClickListener); vback.setOnClickListener(onClickListener); vfastback.setOnClickListener(onClickListener); vfastforword.setOnClickListener(onClickListener); vlast.setOnClickListener(onClickListener); vnext.setOnClickListener(onClickListener); vinfor.setOnClickListener(onClickListener); vseekBar.setOnSeekBarChangeListener(seekBarChangeListener); Bundle bundle=getIntent().getExtras(); vPath=bundle.getString("path"); switchlist=bundle.getBoolean("switch"); surfaceHolder=surfaceView.getHolder(); try { mediaPlayer.setDataSource(vPath); } catch (IOException e) { e.printStackTrace(); } vFile=new File(vPath); videolist=dataProvider.getVideo(); for (int i = 0;i < videolist.size(); i++){ if (vPath.equals(videolist.get(i).filePath)){ fileIndex = i; } } vtitle.setText(vFile.getName()); mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { vseekBar.setProgress(0); vgress.setText(Tool.millisToStringShort(0)); total=mediaPlayer.getDuration(); vtotal.setText(Tool.millisToStringShort(total)); vseekBar.setMax(total); } }); mediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() { //尺寸变化回调 @Override public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { changeVideoSize(); } }); mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { vseekBar.setProgress(0); vpause.setVisibility(View.GONE); vplay.setVisibility(View.VISIBLE); relativeLayout1.setVisibility(View.VISIBLE); relativeLayout2.setVisibility(View.VISIBLE); } }); surfaceHolder.addCallback(new SurfaceHolder.Callback() { //当SurfaceView中Surface创建时回掉 //该方法表示Surface已经创建完成,可以在该方法中进行绘图操作 @Override public void surfaceCreated(@NonNull SurfaceHolder holder) { mediaPlayer.reset(); try { //设置视屏文件图像的显示参数 mediaPlayer.setDisplay(holder); //file.getAbsolutePath()本地视频 //uri 网络视频 mediaPlayer.setDataSource(context, Uri.parse(vPath)); //prepare();表示准备工作同步进行,(准备工作在UI线程中进行) //当播放网络视频时,如果网络不要 会报ARN 所以不采用该方法 //mediaPlayer.prepare(); //异步准备 准备工作在子线程中进行 当播放网络视频时候一般采用此方法 mediaPlayer.prepareAsync(); } catch (IOException e) { e.printStackTrace(); } } //当SurfaceView的大小发生改变时候触发该方法 @Override public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) { } //Surface销毁时回调 //当Surface销毁时候,同时把MediaPlayer也销毁 @Override public void surfaceDestroyed(@NonNull SurfaceHolder holder) { if (mediaPlayer!=null) { mediaPlayer.stop(); //释放资源 mediaPlayer.release(); } } }); //设置 surfaceView点击监听 surfaceView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (mediaPlayer.isPlaying()) { mediaPlayer.pause(); relativeLayout1.setVisibility(View.VISIBLE); relativeLayout2.setVisibility(View.VISIBLE); vplay.setVisibility(View.VISIBLE); vpause.setVisibility(View.GONE); } else { mediaPlayer.start(); relativeLayout1.setVisibility(View.GONE); relativeLayout2.setVisibility(View.GONE); vplay.setVisibility(View.GONE); vpause.setVisibility(View.GONE); } break; } //返回True代表事件已经处理了 return true; } }); } private void initInfoView() { infoView = View.inflate(this, R.layout.information, null); nameTv = infoView.findViewById(R.id.tv_name); createTv = infoView.findViewById(R.id.tv_create); sizeTv = infoView.findViewById(R.id.tv_size); formatTv = infoView.findViewById(R.id.tv_format); resolutionTv = infoView.findViewById(R.id.tv_resolution); pathTv = infoView.findViewById(R.id.tv_path); int index = vFile.getName().lastIndexOf("."); if (index > 0) { nameTv.setText("文件名: "+ vFile.getName().substring(0, index)); formatTv.setText("类型: "+ vFile.getName().substring(index)); } else { nameTv.setText("文件名: "+ vFile.getName()); formatTv.setText("类型: 未知"); } SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); if(!switchlist){ createTv.setText("新建时间: 无法识别"); resolutionTv.setText("分辨率:无法识别"); sizeTv.setText("文件大小: 无法识别"); pathTv.setText("文件路径: "+ vPath); }else { createTv.setText("新建时间: "+ format.format(vFile.lastModified())); MediaMetadataRetriever retr = new MediaMetadataRetriever(); retr.setDataSource(vPath); String height = retr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT); // 视频高度 String width = retr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH); // 视频宽度 if (height!=null&&width!=null){ resolutionTv.setText("分辨率:"+width+"*"+height); }else { resolutionTv.setText("分辨率:无法识别"); } sizeTv.setText("文件大小: "+ Tool.formatSize(vFile.length())); pathTv.setText("文件路径: "+ vPath); } } private void createInfoDialog() { DisplayMetrics dm= getResources().getDisplayMetrics(); windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; params.gravity = Gravity.TOP | Gravity.START; params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; params.width = (int) (dm.widthPixels*0.3); params.height = (int) (dm.heightPixels*0.2); params.x = dm.widthPixels; params.y = (int) (dm.heightPixels*0.6); params.format = PixelFormat.RGBA_8888; windowManager.addView(infoView, params); } public void next() { if (fileIndex + 1 == videolist.size()){ fileIndex = 0; }else { fileIndex++; } vPath = videolist.get(fileIndex).filePath; vFile=new File(vPath); initActivity(); initInfoView(); } public void last() { if (fileIndex == 0){ fileIndex = videolist.size()-1; }else { fileIndex--; } vPath = videolist.get(fileIndex).filePath; vFile=new File(vPath); initActivity(); initInfoView(); } public void initActivity(){ try { if(mediaPlayer !=null){ mediaPlayer.stop(); } mediaPlayer.reset(); mediaPlayer.setDataSource(vPath); vtitle.setText(vFile.getName()); mediaPlayer.setDisplay(surfaceHolder); mediaPlayer.prepareAsync(); } catch (IOException e) { e.printStackTrace(); } } public SeekBar.OnSeekBarChangeListener seekBarChangeListener=new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (!mediaPlayer.isPlaying()){ mediaPlayer.seekTo(seekBar.getProgress(),MediaPlayer.SEEK_CLOSEST); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { handler.removeMessages(1); mediaPlayer.pause(); } @Override public void onStopTrackingTouch(SeekBar seekBar) { mediaPlayer.start(); handler.sendEmptyMessage(1); } }; public View.OnClickListener onClickListener=new View.OnClickListener() { @Override public void onClick(View v) { int itemId = v.getId(); if (itemId == R.id.videoback) { if (!isInfoDialogShow){ windowManager.removeView(infoView); isInfoDialogShow=true; } handler.removeMessages(1); finish(); } else if (itemId == R.id.videoplay) { mediaPlayer.start(); vplay.setVisibility(View.GONE); vpause.setVisibility(View.VISIBLE); handler.sendEmptyMessage(1); handler.postDelayed(new Runnable() { @Override public void run() { relativeLayout1.setVisibility(View.GONE); relativeLayout2.setVisibility(View.GONE); vpause.setVisibility(View.GONE); vplay.setVisibility(View.GONE); } }, 3000); } else if (itemId == R.id.videopause) { mediaPlayer.pause(); vplay.setVisibility(View.VISIBLE); vpause.setVisibility(View.GONE); handler.removeMessages(1); } else if (itemId == R.id.videofastforward) { int i=0; i+=2000; mediaPlayer.seekTo(nowtime+i,MediaPlayer.SEEK_CLOSEST); } else if (itemId == R.id.videofastback) { int j=0; j-=2000; mediaPlayer.seekTo(nowtime+j,MediaPlayer.SEEK_CLOSEST); } else if (itemId == R.id.videolast) { if (!switchlist){ Toast.makeText(context,"无",Toast.LENGTH_SHORT).show(); }else { if (!isInfoDialogShow){ windowManager.removeView(infoView); isInfoDialogShow=true; } last(); vplay.setVisibility(View.VISIBLE); vpause.setVisibility(View.GONE); } } else if (itemId == R.id.videonext) { if (!switchlist){ Toast.makeText(context,"无",Toast.LENGTH_SHORT).show(); }else { if (!isInfoDialogShow){ windowManager.removeView(infoView); isInfoDialogShow=true; } next(); vplay.setVisibility(View.VISIBLE); vpause.setVisibility(View.GONE); } } else if (itemId == R.id.videoinfor) { isInfoDialogShow=!isInfoDialogShow; if (isInfoDialogShow) { windowManager.removeView(infoView); } else { createInfoDialog(); } } } }; public void changeVideoSize() { int videoWidth = mediaPlayer.getVideoWidth(); int videoHeight = mediaPlayer.getVideoHeight(); int deviceWidth = getResources().getDisplayMetrics().widthPixels; int deviceHeight = getResources().getDisplayMetrics().heightPixels; float devicePercent = 0; //下面进行求屏幕比例,因为横竖屏会改变屏幕宽度值,所以为了保持更小的值除更大的值. if (getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) { //竖屏 devicePercent = (float) deviceWidth / (float) deviceHeight; //竖屏状态下宽度小与高度,求比 }else { //横屏 devicePercent = (float) deviceHeight / (float) deviceWidth; //横屏状态下高度小与宽度,求比 } if (videoWidth > videoHeight){ //判断视频的宽大于高,那么我们就优先满足视频的宽度铺满屏幕的宽度,然后在按比例求出合适比例的高度 videoWidth = deviceWidth;//将视频宽度等于设备宽度,让视频的宽铺满屏幕 videoHeight = (int)(deviceWidth*devicePercent);//设置了视频宽度后,在按比例算出视频高度 }else { //判断视频的高大于宽,那么我们就优先满足视频的高度铺满屏幕的高度,然后在按比例求出合适比例的宽度 if (getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {//竖屏 videoHeight = deviceHeight; /** * 接受在宽度的轻微拉伸来满足视频铺满屏幕的优化 */ float videoPercent = (float) videoWidth / (float) videoHeight;//求视频比例 注意是宽除高 与 上面的devicePercent 保持一致 float differenceValue = Math.abs(videoPercent - devicePercent);//相减求绝对值 if (differenceValue < 0.3){ //如果小于0.3比例,那么就放弃按比例计算宽度直接使用屏幕宽度 videoWidth = deviceWidth; }else { videoWidth = (int)(videoWidth/devicePercent);//注意这里是用视频宽度来除 } }else { //横屏 videoHeight = deviceHeight; videoWidth = (int)(deviceHeight*devicePercent); } } FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) surfaceView.getLayoutParams(); layoutParams.width = videoWidth; layoutParams.height = videoHeight; surfaceView.setLayoutParams(layoutParams); } @Override protected void onResume() { super.onResume(); } @Override protected void onPause() { super.onPause(); } @Override protected void onDestroy() { super.onDestroy(); } }
10-29
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值