surfaceView设置RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT后竖屏的视频,会挤压成横屏
时间: 2023-12-14 12:36:05 浏览: 34
这可能是因为您的视频源的宽高比与您的设备屏幕的宽高比不同。当您将SurfaceView的LayoutParams设置为MATCH_PARENT时,它会填充整个父布局,但是如果视频源与屏幕的宽高比不同,则会出现挤压或拉伸的情况。
为了解决这个问题,您可以尝试使用以下方法之一:
1. 在布局文件中,将SurfaceView的LayoutParams设置为WRAP_CONTENT,并将其放置在一个竖直方向的LinearLayout中。然后,您可以通过旋转LinearLayout来实现横屏显示,同时保持视频的纵横比不变。
2. 在代码中,您可以通过检测设备的方向并根据需要旋转SurfaceView来实现横屏。例如,您可以使用以下代码:
```
int rotation = getWindowManager().getDefaultDisplay().getRotation();
if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
surfaceView.setRotation(90);
}
```
这将在设备旋转时自动调整SurfaceView的方向。请注意,您还需要根据需要调整视频源的方向,以确保它正确地显示在SurfaceView中。
相关问题
surfaceview播放视频 竖屏activity中启动另一个横屏activity实现代码
在竖屏的Activity中启动横屏的Activity,可以在Intent中设置横屏的Activity的屏幕方向为横屏,然后在横屏的Activity中使用SurfaceView播放视频。
以下是示例代码:
竖屏的Activity:
```java
public class VerticalActivity extends AppCompatActivity {
private static final String TAG = "VerticalActivity";
// 启动横屏的Activity
private void startHorizontalActivity() {
Intent intent = new Intent(this, HorizontalActivity.class);
intent.putExtra("SCREEN_ORIENTATION", ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
startActivity(intent);
}
// 在竖屏状态下按下按钮,启动横屏的Activity
public void onClickButton(View view) {
startHorizontalActivity();
}
}
```
横屏的Activity:
```java
public class HorizontalActivity extends AppCompatActivity {
private static final String TAG = "HorizontalActivity";
private SurfaceView mSurfaceView;
private MediaPlayer mMediaPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 获取Intent中的屏幕方向参数
int orientation = getIntent().getIntExtra("SCREEN_ORIENTATION", ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setRequestedOrientation(orientation); // 设置屏幕方向
setContentView(R.layout.activity_horizontal);
mSurfaceView = findViewById(R.id.surface_view);
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setSurface(mSurfaceView.getHolder().getSurface()); // 设置MediaPlayer的Surface
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start(); // 准备完成后开始播放
}
});
try {
mMediaPlayer.setDataSource("video.mp4"); // 设置视频文件路径
mMediaPlayer.prepareAsync(); // 异步准备MediaPlayer
} catch (IOException e) {
Log.e(TAG, "Failed to set data source", e);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mMediaPlayer.release(); // 释放MediaPlayer资源
}
}
```
其中,`activity_horizontal.xml`文件中添加了一个`SurfaceView`:
```xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<SurfaceView
android:id="@+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
```
at android.media.MediaPlayer._setVideoSurface(Native method)
这是一个 Android 平台上的 MediaPlayer 类的本地方法,用于设置视频渲染表面。它是 MediaPlayer 类内部的私有方法,并不是公开的 API,因此我们无法直接调用它。通常情况下,我们可以通过调用 MediaPlayer 类的 setSurface() 方法,将一个 Surface 对象传递给 MediaPlayer 对象,以便让 MediaPlayer 在该 Surface 上渲染视频。具体来说,可以通过以下方式设置 Surface:
```java
MediaPlayer mediaPlayer = new MediaPlayer();
SurfaceView surfaceView = findViewById(R.id.surface_view);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
mediaPlayer.setDisplay(holder);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// do nothing
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mediaPlayer.setDisplay(null);
}
});
```
在上面的代码中,我们创建了一个 MediaPlayer 对象和一个 SurfaceView 对象,然后通过 SurfaceView 的 getHolder() 方法获取其关联的 SurfaceHolder 对象。接下来,我们通过 SurfaceHolder 的 addCallback() 方法注册了一个回调函数,用于监听 Surface 的创建、改变和销毁事件。在回调函数中,我们将 SurfaceHolder 对象传递给 MediaPlayer 对象的 setDisplay() 方法,以便让 MediaPlayer 在该 Surface 上渲染视频。当 Surface 销毁时,我们需要将 MediaPlayer 的显示表面设置为 null,以便 MediaPlayer 停止渲染视频。