Mini player, ExpandableSurfaceView with ZOOM support, popup

- mini player's title, image and author information will be updated in many situations but the main idea is that the info will be the same as currently playing stream. If nothing played then you'll see the info about currently opened stream in fragment. When MainPlayer service stops the info updates too
- made ExpandableSurfaceView to replace AspectRatioFrameLayout. The reason for that is to make possible to use aspect ratio mode ZOOM. It's impossible to show a stream inside AspectRatioFrameLayout with ZOOM mode and to fit the video view to a screen space at the same time. Now the new view able to do that and to show vertical videos in a slightly wide space for them
- refactored some methods to make the code more understandable
- made fixes for player view for landscape-to-landscape orientation change
- added Java docs
- adapted swipe tracking inside bottom sheet
- fixed PlayQueue crashes on clearing
- paddings for popup player now as small as possible
This commit is contained in:
Avently 2020-02-05 08:59:30 +03:00
parent 26e487c01a
commit f334a2740f
14 changed files with 405 additions and 225 deletions

View file

@ -0,0 +1,102 @@
package org.schabi.newpipe.views;
import android.content.Context;
import android.util.AttributeSet;
import android.view.SurfaceView;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
import static com.google.android.exoplayer2.ui.AspectRatioFrameLayout.*;
public class ExpandableSurfaceView extends SurfaceView {
private int resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT;
private int baseHeight = 0;
private int maxHeight = 0;
private float videoAspectRatio = 0f;
private float scaleX = 1.0f;
private float scaleY = 1.0f;
public ExpandableSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (videoAspectRatio == 0f) return;
int width = MeasureSpec.getSize(widthMeasureSpec);
boolean verticalVideo = videoAspectRatio < 1;
// Use maxHeight only on non-fit resize mode and in vertical videos
int height = maxHeight != 0 && resizeMode != AspectRatioFrameLayout.RESIZE_MODE_FIT && verticalVideo ? maxHeight : baseHeight;
if (height == 0) return;
float viewAspectRatio = width / ((float) height);
float aspectDeformation = videoAspectRatio / viewAspectRatio - 1;
scaleX = 1.0f;
scaleY = 1.0f;
switch (resizeMode) {
case AspectRatioFrameLayout.RESIZE_MODE_FIT:
if (aspectDeformation > 0) {
height = (int) (width / videoAspectRatio);
} else {
width = (int) (height * videoAspectRatio);
}
break;
case RESIZE_MODE_ZOOM:
if (aspectDeformation < 0) {
scaleY = viewAspectRatio / videoAspectRatio;
} else {
scaleX = videoAspectRatio / viewAspectRatio;
}
break;
default:
break;
}
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
}
/**
* Scale view only in {@link #onLayout} to make transition for ZOOM mode as smooth as possible
*/
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
setScaleX(scaleX);
setScaleY(scaleY);
}
/**
* @param base The height that will be used in every resize mode as a minimum height
* @param max The max height for vertical videos in non-FIT resize modes
*/
public void setHeights(int base, int max) {
if (baseHeight == base && maxHeight == max) return;
baseHeight = base;
maxHeight = max;
requestLayout();
}
@AspectRatioFrameLayout.ResizeMode
public void setResizeMode(int newResizeMode) {
if (resizeMode == newResizeMode) return;
resizeMode = newResizeMode;
requestLayout();
}
@AspectRatioFrameLayout.ResizeMode
public int getResizeMode() {
return resizeMode;
}
public void setAspectRatio(float aspectRatio) {
if (videoAspectRatio == aspectRatio) return;
videoAspectRatio = aspectRatio;
requestLayout();
}
}