问题
I have a RelativeLayout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:foregroundGravity="center"
android:gravity="center"
android:orientation="horizontal" >
<VideoView
android:id="@+id/videoViewPanel"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:layout_centerInParent="true"/>
</RelativeLayout>
And what I need is to show video fullscreen cropped. If I could compare to ImageView, I need to show it as crop_center.
How can I make VideoView not to auto-resize video to fit center, but crop center?
回答1:
The solution is to use TextureView
instead of VideoView
(SurfaceView
).TextureView
does not make any manipulations with the content to fit it ti the screen.
Here is the code sample for the solution:
//store the SurfaceTexture to set surface for MediaPlayer
mTextureView.setSurfaceTextureListener(new SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface,
int width, int height) {
FullScreenActivity.this.mSurface = surface;
}
....
Surface s = new Surface(mSurface);
mPlayer = mp;
mp.setSurface(s);
scaleVideo(mp);//<-- this function scales video to run cropped
....
private void scaleVideo(MediaPlayer mPlayer) {
LayoutParams videoParams = (LayoutParams) mTextureView
.getLayoutParams();
DisplayMetrics dm = new DisplayMetrics();
FullScreenActivity.this.getWindowManager().getDefaultDisplay()
.getMetrics(dm);
final int height = dm.heightPixels;
final int width = dm.widthPixels;
int videoHeight = mPlayer.getVideoHeight();
int videoWidth = mPlayer.getVideoWidth();
double hRatio = 1;
hRatio = (height * 1.0 / videoHeight) / (width * 1.0 / videoWidth);
videoParams.x = (int) (hRatio <= 1 ? 0 : Math.round((-(hRatio - 1) / 2)
* width));
videoParams.y = (int) (hRatio >= 1 ? 0 : Math
.round((((-1 / hRatio) + 1) / 2) * height));
videoParams.width = width - videoParams.x - videoParams.x;
videoParams.height = height - videoParams.y - videoParams.y;
Log.e(TAG, "x:" + videoParams.x + " y:" + videoParams.y);
mTextureView.setScaleX(1.00001f);//<-- this line enables smoothing of the picture in TextureView.
mTextureView.requestLayout();
mTextureView.invalidate();
}
回答2:
To crop center in fullscreen you can still use a VideoView. Set the VideoView width and height to match the parent inside a RelativeLayout and adjust it to be bigger than the screen and set his position.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/rootLayout"
tools:context="com.example.Activity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_height="match_parent">
<VideoView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_centerVertical="true" />
</RelativeLayout>
</RelativeLayout>
And then in onCreate:
RelativeLayout rootView=(RelativeLayout) findViewById(R.id.rootLayout);
Display display=getWindowManager().getDefaultDisplay();
Point size=new Point();
display.getSize(size);
FrameLayout.LayoutParams rootViewParams = (FrameLayout.LayoutParams) rootView.getLayoutParams();
int videoWidth=864;
int videoHeight=1280;
if ((float)videoWidth/(float)videoHeight<(float)size.x/(float)size.y) {
rootViewParams.width=size.x;
rootViewParams.height=videoHeight*size.x/videoWidth;
rootView.setX(0);
rootView.setY((rootViewParams.height-size.y)/2*-1);
} else {
rootViewParams.width=videoWidth*size.y/videoHeight;
rootViewParams.height=size.y;
rootView.setX((rootViewParams.width-size.x)/2*-1);
rootView.setY(0);
}
rootView.setLayoutParams(rootViewParams);
final VideoView mVideoView=(VideoView)findViewById(R.id.video_view);
mVideoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.splash));
mVideoView.requestFocus();
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mVideoView.start();
}
});
回答3:
I have found a solution: The default behavior is just like fitCenter
, so I compute the video ratio(width/height) and screen ratio, and then scale the VideoView
to full screen. The result is just like centerCrop
.
回答4:
I just put video inside ConstraintLayout
with such parameters. This helped stretch video and achieve android:scaleType="centerCrop"
effect.
<VideoView
android:id="@+id/video_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_gravity="center_horizontal"
android:layout_width="0dp"
android:layout_height="0dp" />
来源:https://stackoverflow.com/questions/19429811/android-videoview-crop-center