开始播放界面相关UI调整

pull/1/head
DreamDSTR 4 years ago
parent 730de45127
commit 5dd9798ccd
  1. 69
      app/src/main/java/com/github/tvbox/osc/picasso/RoundTransformation.java
  2. 437
      app/src/main/java/com/github/tvbox/osc/player/controller/BaseController.java
  3. 225
      app/src/main/java/com/github/tvbox/osc/player/controller/VodController.java
  4. 57
      app/src/main/java/com/github/tvbox/osc/ui/activity/PlayActivity.java
  5. 18
      app/src/main/java/com/github/tvbox/osc/ui/fragment/UserFragment.java
  6. 22
      app/src/main/res/drawable/shape_player_control_vod_seek.xml
  7. 7
      app/src/main/res/drawable/shape_player_control_vod_seek_thumb.xml
  8. 8
      app/src/main/res/drawable/shape_player_control_vod_seek_thumb_normal.xml
  9. 8
      app/src/main/res/drawable/shape_player_control_vod_seek_thumb_press.xml
  10. 0
      app/src/main/res/drawable/shape_thumb_bottom_name.xml
  11. 12
      app/src/main/res/layout/activity_projection_play.xml
  12. 4
      app/src/main/res/layout/item_grid.xml
  13. 2
      app/src/main/res/layout/item_search.xml
  14. 6
      app/src/main/res/layout/item_user_hot_vod.xml
  15. 4
      app/src/main/res/layout/loadsir_loading_layout.xml
  16. 322
      app/src/main/res/layout/player_vod_control_view.xml

@ -6,6 +6,7 @@ import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Shader;
@ -25,7 +26,7 @@ import java.lang.annotation.Target;
* @since 2020/12/22
*/
public class RoundTransformation implements Transformation {
private int viewWidth, viewHeight;
private int viewWidth, viewHeight, bottomShapeHeight = 0;
@RoundType
private int mRoundType = RoundType.NONE;
private int diameter;
@ -48,6 +49,11 @@ public class RoundTransformation implements Transformation {
return this;
}
public RoundTransformation bottomShapeHeight(int shapeHeight) {
this.bottomShapeHeight = shapeHeight;
return this;
}
public RoundTransformation roundRadius(int radius, @RoundType int mRoundType) {
this.radius = radius;
this.diameter = radius * 2;
@ -92,6 +98,63 @@ public class RoundTransformation implements Transformation {
return bitmap;
}
static Path RoundedRect(float left, float top, float right, float bottom, float rx, float ry, boolean tl, boolean tr, boolean br, boolean bl) {
Path path = new Path();
if (rx < 0) rx = 0;
if (ry < 0) ry = 0;
float width = right - left;
float height = bottom - top;
if (rx > width / 2) rx = width / 2;
if (ry > height / 2) ry = height / 2;
float widthMinusCorners = (width - (2 * rx));
float heightMinusCorners = (height - (2 * ry));
path.moveTo(right, top + ry);
if (tr)
path.rQuadTo(0, -ry, -rx, -ry);//top-right corner
else {
path.rLineTo(0, -ry);
path.rLineTo(-rx, 0);
}
path.rLineTo(-widthMinusCorners, 0);
if (tl)
path.rQuadTo(-rx, 0, -rx, ry); //top-left corner
else {
path.rLineTo(-rx, 0);
path.rLineTo(0, ry);
}
path.rLineTo(0, heightMinusCorners);
if (bl)
path.rQuadTo(0, ry, rx, ry);//bottom-left corner
else {
path.rLineTo(0, ry);
path.rLineTo(rx, 0);
}
path.rLineTo(widthMinusCorners, 0);
if (br)
path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner
else {
path.rLineTo(rx, 0);
path.rLineTo(0, -ry);
}
path.rLineTo(0, -heightMinusCorners);
path.close();//Given close, last lineto can be removed.
return path;
}
private void drawBottomLabel(Canvas mCanvas, Paint mPaint, float left, float top, float right, float bottom) {
if (bottomShapeHeight <= 0)
return;
mPaint.setShader(null);
mPaint.setColor(0x99000000);
mCanvas.drawPath(RoundedRect(left, bottom - bottomShapeHeight * 2, right, bottom, radius, radius, false, false, true, true), mPaint);
}
private void drawRoundRect(Canvas mCanvas, Paint mPaint, float width, float height) {
switch (mRoundType) {
case RoundType.NONE:
@ -116,18 +179,22 @@ public class RoundTransformation implements Transformation {
case RoundType.ALL:
if (viewWidth == width && viewHeight == height) {
mCanvas.drawRoundRect(new RectF(0, 0, viewWidth, viewHeight), radius, radius, mPaint);
drawBottomLabel(mCanvas, mPaint, 0, 0, viewWidth, viewHeight);
} else if (viewWidth == width && viewHeight != height) {
float dis = (height - viewHeight) / 2f;
if (isCenterCorp) {
mCanvas.translate(0, -dis);
mCanvas.drawRoundRect(new RectF(0, dis, viewWidth, viewHeight + dis), radius, radius, mPaint);
drawBottomLabel(mCanvas, mPaint, 0, dis, viewWidth, viewHeight + dis);
} else {
mCanvas.drawRoundRect(new RectF(0, 0, viewWidth, viewHeight), radius, radius, mPaint);
drawBottomLabel(mCanvas, mPaint, 0, 0, viewWidth, viewHeight);
}
} else {
float dis = (width - viewWidth) / 2f;
mCanvas.translate(-dis, 0);
mCanvas.drawRoundRect(new RectF(dis, 0, viewWidth + dis, viewHeight), radius, radius, mPaint);
drawBottomLabel(mCanvas, mPaint, dis, 0, viewWidth + dis, viewHeight);
}
break;
case RoundType.TOP:

@ -0,0 +1,437 @@
package com.github.tvbox.osc.player.controller;
import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.Map;
import xyz.doikki.videoplayer.controller.BaseVideoController;
import xyz.doikki.videoplayer.controller.IControlComponent;
import xyz.doikki.videoplayer.controller.IGestureComponent;
import xyz.doikki.videoplayer.player.VideoView;
import xyz.doikki.videoplayer.util.PlayerUtils;
public abstract class BaseController extends BaseVideoController implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener, View.OnTouchListener {
private GestureDetector mGestureDetector;
private AudioManager mAudioManager;
private boolean mIsGestureEnabled = true;
private int mStreamVolume;
private float mBrightness;
private int mSeekPosition;
private boolean mFirstTouch;
private boolean mChangePosition;
private boolean mChangeBrightness;
private boolean mChangeVolume;
private boolean mCanChangePosition = true;
private boolean mEnableInNormal;
private boolean mCanSlide;
private int mCurPlayState;
protected Handler mHandler;
protected HandlerCallback mHandlerCallback;
protected interface HandlerCallback {
void callback(Message msg);
}
private boolean mIsDoubleTapTogglePlayEnabled = true;
public BaseController(@NonNull Context context) {
super(context);
mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
int what = msg.what;
switch (what) {
case 100: { // 亮度+音量调整
mSlideInfo.setVisibility(VISIBLE);
mSlideInfo.setText(msg.obj.toString());
break;
}
case 101: { // 亮度+音量调整 关闭
mSlideInfo.setVisibility(GONE);
break;
}
default: {
if (mHandlerCallback != null)
mHandlerCallback.callback(msg);
break;
}
}
return false;
}
});
}
public BaseController(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public BaseController(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
TextView mSlideInfo;
ProgressBar mLoading;
ViewGroup mPauseRoot;
TextView mPauseTime;
@Override
protected void initView() {
super.initView();
mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
mGestureDetector = new GestureDetector(getContext(), this);
setOnTouchListener(this);
mSlideInfo = findViewWithTag("vod_control_slide_info");
mLoading = findViewWithTag("vod_control_loading");
mPauseRoot = findViewWithTag("vod_control_pause");
mPauseTime = findViewWithTag("vod_control_pause_t");
}
@Override
protected void setProgress(int duration, int position) {
super.setProgress(duration, position);
mPauseTime.setText(PlayerUtils.stringForTime(position) + " / " + PlayerUtils.stringForTime(duration));
}
@Override
protected void onPlayStateChanged(int playState) {
super.onPlayStateChanged(playState);
switch (playState) {
case VideoView.STATE_IDLE:
mLoading.setVisibility(GONE);
break;
case VideoView.STATE_PLAYING:
mPauseRoot.setVisibility(GONE);
mLoading.setVisibility(GONE);
break;
case VideoView.STATE_PAUSED:
mPauseRoot.setVisibility(VISIBLE);
mLoading.setVisibility(GONE);
break;
case VideoView.STATE_PREPARED:
case VideoView.STATE_ERROR:
case VideoView.STATE_BUFFERED:
mLoading.setVisibility(GONE);
break;
case VideoView.STATE_PREPARING:
case VideoView.STATE_BUFFERING:
mLoading.setVisibility(VISIBLE);
break;
case VideoView.STATE_PLAYBACK_COMPLETED:
mLoading.setVisibility(GONE);
mPauseRoot.setVisibility(GONE);
break;
}
}
/**
* 设置是否可以滑动调节进度默认可以
*/
public void setCanChangePosition(boolean canChangePosition) {
mCanChangePosition = canChangePosition;
}
/**
* 是否在竖屏模式下开始手势控制默认关闭
*/
public void setEnableInNormal(boolean enableInNormal) {
mEnableInNormal = enableInNormal;
}
/**
* 是否开启手势控制默认开启关闭之后手势调节进度音量亮度功能将关闭
*/
public void setGestureEnabled(boolean gestureEnabled) {
mIsGestureEnabled = gestureEnabled;
}
/**
* 是否开启双击播放/暂停默认开启
*/
public void setDoubleTapTogglePlayEnabled(boolean enabled) {
mIsDoubleTapTogglePlayEnabled = enabled;
}
@Override
public void setPlayerState(int playerState) {
super.setPlayerState(playerState);
if (playerState == VideoView.PLAYER_NORMAL) {
mCanSlide = mEnableInNormal;
} else if (playerState == VideoView.PLAYER_FULL_SCREEN) {
mCanSlide = true;
}
}
@Override
public void setPlayState(int playState) {
super.setPlayState(playState);
mCurPlayState = playState;
}
protected boolean isInPlaybackState() {
return mControlWrapper != null
&& mCurPlayState != VideoView.STATE_ERROR
&& mCurPlayState != VideoView.STATE_IDLE
&& mCurPlayState != VideoView.STATE_PREPARING
&& mCurPlayState != VideoView.STATE_PREPARED
&& mCurPlayState != VideoView.STATE_START_ABORT
&& mCurPlayState != VideoView.STATE_PLAYBACK_COMPLETED;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
/**
* 手指按下的瞬间
*/
@Override
public boolean onDown(MotionEvent e) {
if (!isInPlaybackState() //不处于播放状态
|| !mIsGestureEnabled //关闭了手势
|| PlayerUtils.isEdge(getContext(), e)) //处于屏幕边沿
return true;
mStreamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
Activity activity = PlayerUtils.scanForActivity(getContext());
if (activity == null) {
mBrightness = 0;
} else {
mBrightness = activity.getWindow().getAttributes().screenBrightness;
}
mFirstTouch = true;
mChangePosition = false;
mChangeBrightness = false;
mChangeVolume = false;
return true;
}
/**
* 单击
*/
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if (isInPlaybackState()) {
mControlWrapper.toggleShowState();
}
return true;
}
/**
* 双击
*/
@Override
public boolean onDoubleTap(MotionEvent e) {
if (mIsDoubleTapTogglePlayEnabled && !isLocked() && isInPlaybackState()) togglePlay();
return true;
}
/**
* 在屏幕上滑动
*/
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (!isInPlaybackState() //不处于播放状态
|| !mIsGestureEnabled //关闭了手势
|| !mCanSlide //关闭了滑动手势
|| isLocked() //锁住了屏幕
|| PlayerUtils.isEdge(getContext(), e1)) //处于屏幕边沿
return true;
float deltaX = e1.getX() - e2.getX();
float deltaY = e1.getY() - e2.getY();
if (mFirstTouch) {
mChangePosition = Math.abs(distanceX) >= Math.abs(distanceY);
if (!mChangePosition) {
//半屏宽度
int halfScreen = PlayerUtils.getScreenWidth(getContext(), true) / 2;
if (e2.getX() > halfScreen) {
mChangeVolume = true;
} else {
mChangeBrightness = true;
}
}
if (mChangePosition) {
//根据用户设置是否可以滑动调节进度来决定最终是否可以滑动调节进度
mChangePosition = mCanChangePosition;
}
if (mChangePosition || mChangeBrightness || mChangeVolume) {
for (Map.Entry<IControlComponent, Boolean> next : mControlComponents.entrySet()) {
IControlComponent component = next.getKey();
if (component instanceof IGestureComponent) {
((IGestureComponent) component).onStartSlide();
}
}
}
mFirstTouch = false;
}
if (mChangePosition) {
slideToChangePosition(deltaX);
} else if (mChangeBrightness) {
slideToChangeBrightness(deltaY);
} else if (mChangeVolume) {
slideToChangeVolume(deltaY);
}
return true;
}
protected void slideToChangePosition(float deltaX) {
deltaX = -deltaX;
int width = getMeasuredWidth();
int duration = (int) mControlWrapper.getDuration();
int currentPosition = (int) mControlWrapper.getCurrentPosition();
int position = (int) (deltaX / width * 120000 + currentPosition);
if (position > duration) position = duration;
if (position < 0) position = 0;
for (Map.Entry<IControlComponent, Boolean> next : mControlComponents.entrySet()) {
IControlComponent component = next.getKey();
if (component instanceof IGestureComponent) {
((IGestureComponent) component).onPositionChange(position, currentPosition, duration);
}
}
updateSeekUI(currentPosition, position, duration);
mSeekPosition = position;
}
protected void updateSeekUI(int curr, int seekTo, int duration) {
}
protected void slideToChangeBrightness(float deltaY) {
Activity activity = PlayerUtils.scanForActivity(getContext());
if (activity == null) return;
Window window = activity.getWindow();
WindowManager.LayoutParams attributes = window.getAttributes();
int height = getMeasuredHeight();
if (mBrightness == -1.0f) mBrightness = 0.5f;
float brightness = deltaY * 2 / height * 1.0f + mBrightness;
if (brightness < 0) {
brightness = 0f;
}
if (brightness > 1.0f) brightness = 1.0f;
int percent = (int) (brightness * 100);
attributes.screenBrightness = brightness;
window.setAttributes(attributes);
for (Map.Entry<IControlComponent, Boolean> next : mControlComponents.entrySet()) {
IControlComponent component = next.getKey();
if (component instanceof IGestureComponent) {
((IGestureComponent) component).onBrightnessChange(percent);
}
}
Message msg = Message.obtain();
msg.what = 100;
msg.obj = "亮度" + percent + "%";
mHandler.sendMessage(msg);
mHandler.removeMessages(101);
mHandler.sendEmptyMessageDelayed(101, 1000);
}
protected void slideToChangeVolume(float deltaY) {
int streamMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
int height = getMeasuredHeight();
float deltaV = deltaY * 2 / height * streamMaxVolume;
float index = mStreamVolume + deltaV;
if (index > streamMaxVolume) index = streamMaxVolume;
if (index < 0) index = 0;
int percent = (int) (index / streamMaxVolume * 100);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int) index, 0);
for (Map.Entry<IControlComponent, Boolean> next : mControlComponents.entrySet()) {
IControlComponent component = next.getKey();
if (component instanceof IGestureComponent) {
((IGestureComponent) component).onVolumeChange(percent);
}
}
Message msg = Message.obtain();
msg.what = 100;
msg.obj = "音量" + percent + "%";
mHandler.sendMessage(msg);
mHandler.removeMessages(101);
mHandler.sendEmptyMessageDelayed(101, 1000);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//滑动结束时事件处理
if (!mGestureDetector.onTouchEvent(event)) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_UP:
stopSlide();
if (mSeekPosition > 0) {
mControlWrapper.seekTo(mSeekPosition);
mSeekPosition = 0;
}
break;
case MotionEvent.ACTION_CANCEL:
stopSlide();
mSeekPosition = 0;
break;
}
}
return super.onTouchEvent(event);
}
private void stopSlide() {
for (Map.Entry<IControlComponent, Boolean> next : mControlComponents.entrySet()) {
IControlComponent component = next.getKey();
if (component instanceof IGestureComponent) {
((IGestureComponent) component).onStopSlide();
}
}
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return false;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
public boolean onKeyEvent(KeyEvent event) {
if (!isInPlaybackState() //不处于播放状态
|| isLocked() //锁住了屏幕
)
return false;
return false;
}
}

@ -0,0 +1,225 @@
package com.github.tvbox.osc.player.controller;
import android.content.Context;
import android.os.Message;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.github.tvbox.osc.R;
import org.jetbrains.annotations.NotNull;
import xyz.doikki.videoplayer.player.VideoView;
import xyz.doikki.videoplayer.util.PlayerUtils;
import static xyz.doikki.videoplayer.util.PlayerUtils.stringForTime;
public class VodController extends BaseController {
public VodController(@NonNull @NotNull Context context) {
super(context);
mHandlerCallback = new HandlerCallback() {
@Override
public void callback(Message msg) {
switch (msg.what) {
case 1000: { // seek 刷新
mProgressRoot.setVisibility(VISIBLE);
break;
}
case 1001: { // seek 关闭
mProgressRoot.setVisibility(GONE);
break;
}
case 1002: { // 显示底部菜单
mBottomRoot.setVisibility(VISIBLE);
break;
}
case 1003: { // 隐藏底部菜单
mBottomRoot.setVisibility(GONE);
break;
}
}
}
};
}
SeekBar mSeekBar;
TextView mCurrentTime;
TextView mTotalTime;
boolean mIsDragging;
LinearLayout mProgressRoot;
TextView mProgressText;
ImageView mProgressIcon;
LinearLayout mBottomRoot;
@Override
protected void initView() {
super.initView();
mCurrentTime = findViewById(R.id.curr_time);
mTotalTime = findViewById(R.id.total_time);
mSeekBar = findViewById(R.id.seekBar);
mProgressRoot = findViewById(R.id.tv_progress_container);
mProgressIcon = findViewById(R.id.tv_progress_icon);
mProgressText = findViewById(R.id.tv_progress_text);
mBottomRoot = findViewById(R.id.bottom_container);
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
int lastProgress = 0;
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (!fromUser) {
return;
}
long duration = mControlWrapper.getDuration();
long newPosition = (duration * progress) / seekBar.getMax();
if (mCurrentTime != null)
mCurrentTime.setText(stringForTime((int) newPosition));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
mIsDragging = true;
mControlWrapper.stopProgress();
mControlWrapper.stopFadeOut();
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
long duration = mControlWrapper.getDuration();
long newPosition = (duration * seekBar.getProgress()) / seekBar.getMax();
mControlWrapper.seekTo((int) newPosition);
mIsDragging = false;
mControlWrapper.startProgress();
mControlWrapper.startFadeOut();
}
});
}
@Override
protected int getLayoutId() {
return R.layout.player_vod_control_view;
}
@Override
protected void setProgress(int duration, int position) {
if (mIsDragging) {
return;
}
super.setProgress(duration, position);
mCurrentTime.setText(PlayerUtils.stringForTime(position));
mTotalTime.setText(PlayerUtils.stringForTime(duration));
if (duration > 0) {
mSeekBar.setEnabled(true);
int pos = (int) (position * 1.0 / duration * mSeekBar.getMax());
mSeekBar.setProgress(pos);
} else {
mSeekBar.setEnabled(false);
}
int percent = mControlWrapper.getBufferedPercentage();
if (percent >= 95) {
mSeekBar.setSecondaryProgress(mSeekBar.getMax());
} else {
mSeekBar.setSecondaryProgress(percent * 10);
}
}
private boolean simSlideStart = false;
private int simSeekPosition = 0;
private long simSlideOffset = 0;
public void tvSlideStop() {
if (!simSlideStart)
return;
mControlWrapper.seekTo(simSeekPosition);
if (!mControlWrapper.isPlaying())
mControlWrapper.start();
simSlideStart = false;
simSeekPosition = 0;
simSlideOffset = 0;
}
public void tvSlideStart(int dir) {
int duration = (int) mControlWrapper.getDuration();
if (duration <= 0)
return;
if (!simSlideStart) {
simSlideStart = true;
}
// 每次10秒
simSlideOffset += (10000.0f * dir);
int currentPosition = (int) mControlWrapper.getCurrentPosition();
int position = (int) (simSlideOffset + currentPosition);
if (position > duration) position = duration;
if (position < 0) position = 0;
updateSeekUI(currentPosition, position, duration);
simSeekPosition = position;
}
@Override
protected void updateSeekUI(int curr, int seekTo, int duration) {
super.updateSeekUI(curr, seekTo, duration);
if (seekTo > curr) {
mProgressIcon.setImageResource(R.drawable.icon_pre);
} else {
mProgressIcon.setImageResource(R.drawable.icon_back);
}
mProgressText.setText(PlayerUtils.stringForTime(seekTo) + " / " + PlayerUtils.stringForTime(duration));
mHandler.sendEmptyMessage(1000);
mHandler.removeMessages(1001);
mHandler.sendEmptyMessageDelayed(1001, 1000);
}
@Override
protected void onPlayStateChanged(int playState) {
super.onPlayStateChanged(playState);
switch (playState) {
case VideoView.STATE_PLAYING:
startProgress();
break;
}
}
@Override
public boolean onKeyEvent(KeyEvent event) {
if (super.onKeyEvent(event)) {
return true;
}
if (isInPlaybackState()) {
int keyCode = event.getKeyCode();
int action = event.getAction();
if (action == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT || keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
tvSlideStart(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT ? 1 : -1);
} else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) {
togglePlay();
} else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
} else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
}
} else if (action == KeyEvent.ACTION_UP) {
if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT || keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
tvSlideStop();
}
}
return super.dispatchKeyEvent(event);
}
return false;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if (isInPlaybackState()) {
mHandler.sendEmptyMessage(1003);
mHandler.removeMessages(1004);
mHandler.sendEmptyMessageDelayed(1004, 3000);
return true;
}
return super.onSingleTapConfirmed(e);
}
}

@ -13,14 +13,12 @@ import com.github.tvbox.osc.base.BaseActivity;
import com.github.tvbox.osc.bean.VodInfo;
import com.github.tvbox.osc.cache.CacheManager;
import com.github.tvbox.osc.event.RefreshEvent;
import com.github.tvbox.osc.player.controller.BoxVideoController;
import com.github.tvbox.osc.player.controller.BoxVodControlView;
import com.github.tvbox.osc.player.controller.VodController;
import com.github.tvbox.osc.ui.dialog.ParseDialog;
import com.github.tvbox.osc.util.HawkConfig;
import com.github.tvbox.osc.util.MD5;
import com.github.tvbox.osc.util.PlayerHelper;
import com.github.tvbox.osc.viewmodel.SourceViewModel;
import com.orhanobut.hawk.Hawk;
import org.greenrobot.eventbus.EventBus;
import org.json.JSONObject;
@ -38,7 +36,7 @@ import xyz.doikki.videoplayer.player.VideoView;
*/
public class PlayActivity extends BaseActivity {
private VideoView mVideoView;
private BoxVideoController controller;
private VodController controller;
private SourceViewModel sourceViewModel;
@Override
@ -86,22 +84,7 @@ public class PlayActivity extends BaseActivity {
}
});
controller = new BoxVideoController(this);
controller.addControlComponent(new GestureView(this));
BoxVodControlView boxVodControlView = new BoxVodControlView(this);
controller.addControlComponent(boxVodControlView);
boxVodControlView.setVodControlListener(new BoxVodControlView.BoxVodControlListener() {
@Override
public void playNext() {
PlayActivity.this.playNext();
}
@Override
public void playPre() {
PlayActivity.this.playPrevious();
}
});
controller = new VodController(this);
controller.setCanChangePosition(true);
controller.setEnableInNormal(true);
controller.setGestureEnabled(true);
@ -174,37 +157,17 @@ public class PlayActivity extends BaseActivity {
@Override
public void onBackPressed() {
if (controller.isBoxTVBottomShow()) {
controller.boxTVBottomToggle();
} else {
super.onBackPressed();
if (controller.onBackPressed()) {
return;
}
super.onBackPressed();
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
int keyCode = event.getKeyCode();
int action = event.getAction();
if (controller.isBoxTVBottomShow()) {
return super.dispatchKeyEvent(event);
}
if (action == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT || keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
controller.boxTVSlideStart(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT ? 1 : -1);
} else if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_NUMPAD_ENTER || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE || (Hawk.get(HawkConfig.DEBUG_OPEN, false) && keyCode == KeyEvent.KEYCODE_0)) {
controller.boxTVTogglePlay();
} else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
// playPrevious();
controller.boxTVBottomToggle();
} else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
// playNext();
controller.boxTVBottomToggle();
}
} else if (action == KeyEvent.ACTION_UP) {
if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT || keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
controller.boxTVSlideStop();
if (event != null) {
if (controller.onKeyEvent(event)) {
return true;
}
}
return super.dispatchKeyEvent(event);
@ -288,7 +251,7 @@ public class PlayActivity extends BaseActivity {
public void play() {
VodInfo.VodSeries vs = mVodInfo.seriesMap.get(mVodInfo.playFlag).get(mVodInfo.playIndex);
EventBus.getDefault().post(new RefreshEvent(RefreshEvent.TYPE_REFRESH, mVodInfo.playIndex));
controller.boxTVRefreshInfo(mVodInfo.name + " " + vs.name + (Hawk.get(HawkConfig.DEBUG_OPEN, false) ? vs.url : ""));
// controller.boxTVRefreshInfo(mVodInfo.name + " " + vs.name + (Hawk.get(HawkConfig.DEBUG_OPEN, false) ? vs.url : ""));
tryDismissParse();

@ -32,6 +32,7 @@ import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.Calendar;
/**
* @author pj567
@ -109,20 +110,25 @@ public class UserFragment extends BaseLazyFragment implements View.OnClickListen
private void initHomeHotVod(HomeHotVodAdapter adapter) {
try {
long time = Hawk.get("douban_hot_date", 0L);
if (System.currentTimeMillis() - time < 6 * 60 * 60 * 1000) {
String json = Hawk.get("douboan_hot", "");
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1;
int day = cal.get(Calendar.DATE);
String today = String.format("%d%d%d", year, month, day);
String requestDay = Hawk.get("home_hot_day", "");
if (requestDay.equals(today)) {
String json = Hawk.get("home_hot", "");
if (!json.isEmpty()) {
adapter.setNewData(loadHots(json));
return;
}
}
OkGo.<String>get("https://movie.douban.com/j/new_search_subjects?sort=R&range=0,10&tags=&playable=1&start=0").execute(new AbsCallback<String>() {
OkGo.<String>get("https://movie.douban.com/j/new_search_subjects?sort=U&range=0,10&tags=&playable=1&start=0&year_range=" + year + "," + year).execute(new AbsCallback<String>() {
@Override
public void onSuccess(Response<String> response) {
String netJson = response.body();
Hawk.put("douban_hot_date", System.currentTimeMillis());
Hawk.put("douboan_hot", netJson);
Hawk.put("home_hot_day", today);
Hawk.put("home_hot", netJson);
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<solid android:color="@color/color_6C3D3D3D" />
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<solid android:color="@color/color_CC353744" />
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<solid android:color="@color/color_353744" />
</shape>
</clip>
</item>
</layer-list>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/shape_player_control_vod_seek_thumb_press" android:state_focused="true" android:state_pressed="true" />
<item android:drawable="@drawable/shape_player_control_vod_seek_thumb_press" android:state_focused="false" android:state_pressed="true" />
<item android:drawable="@drawable/shape_player_control_vod_seek_thumb_normal" android:state_focused="true" android:state_pressed="false" />
<item android:drawable="@drawable/shape_player_control_vod_seek_thumb_normal" />
</selector>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/color_BD0CADE2" />
<size
android:width="@dimen/vs_30"
android:height="@dimen/vs_30" />
</shape>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/color_0CADE2" />
<size
android:width="@dimen/vs_30"
android:height="@dimen/vs_30" />
</shape>

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<xyz.doikki.videoplayer.player.VideoView
android:id="@+id/mVideoView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>

@ -101,7 +101,7 @@
android:id="@+id/tvName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_thumb_buttom_name"
android:background="@drawable/shape_thumb_bottom_name"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:padding="@dimen/vs_5"
@ -113,7 +113,7 @@
android:id="@+id/tvActor"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_thumb_buttom_name"
android:background="@drawable/shape_thumb_bottom_name"
android:ellipsize="end"
android:gravity="top"
android:padding="@dimen/vs_5"

@ -71,7 +71,7 @@
android:id="@+id/tvName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_thumb_buttom_name"
android:background="@drawable/shape_thumb_bottom_name"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:padding="@dimen/vs_5"

@ -38,7 +38,7 @@
android:paddingRight="@dimen/vs_5"
android:singleLine="true"
android:textColor="@android:color/white"
android:textSize="@dimen/ts_16" />
android:textSize="@dimen/ts_20" />
</LinearLayout>
@ -54,13 +54,13 @@
android:id="@+id/tvName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_thumb_buttom_name"
android:background="@drawable/shape_thumb_bottom_name"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:padding="@dimen/vs_5"
android:singleLine="true"
android:textColor="@android:color/white"
android:textSize="@dimen/ts_20" />
android:textSize="@dimen/ts_22" />
</LinearLayout>
</FrameLayout>
</FrameLayout>

@ -4,8 +4,8 @@
android:layout_height="match_parent">
<ProgressBar
android:layout_width="50mm"
android:layout_height="50mm"
android:layout_width="@dimen/vs_50"
android:layout_height="@dimen/vs_50"
android:layout_gravity="center"
android:indeterminateBehavior="repeat"
android:indeterminateDrawable="@drawable/anim_loading"

@ -0,0 +1,322 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/bottom_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@drawable/shape_dialog_filter_bg"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="@dimen/vs_20"
android:paddingTop="@dimen/vs_20"
android:paddingRight="@dimen/vs_20"
android:paddingBottom="@dimen/vs_10"
android:visibility="gone">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/vs_10"
android:orientation="horizontal">
<TextView
android:id="@+id/play_pre"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/vs_10"
android:layout_marginRight="@dimen/vs_10"
android:background="@drawable/button_dialog_main"
android:padding="@dimen/vs_10"
android:text="上一集"
android:textColor="@android:color/white"
android:textSize="@dimen/ts_20" />
<TextView
android:id="@+id/play_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/vs_10"
android:layout_marginRight="@dimen/vs_10"
android:background="@drawable/button_dialog_main"
android:padding="@dimen/vs_10"
android:text="下一集"
android:textColor="@android:color/white"
android:textSize="@dimen/ts_20" />
<TextView
android:id="@+id/play_player"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/vs_10"
android:layout_marginRight="@dimen/vs_10"
android:background="@drawable/button_dialog_main"
android:padding="@dimen/vs_10"
android:text="系统播放器"
android:textColor="@android:color/white"
android:textSize="@dimen/ts_20" />
<TextView
android:id="@+id/play_ijk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/vs_10"
android:layout_marginRight="@dimen/vs_10"
android:background="@drawable/button_dialog_main"
android:padding="@dimen/vs_10"
android:text="硬解码"
android:textColor="@android:color/white"
android:textSize="@dimen/ts_20" />
<TextView
android:id="@+id/play_scale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/vs_10"
android:layout_marginRight="@dimen/vs_10"
android:background="@drawable/button_dialog_main"
android:padding="@dimen/vs_10"
android:text="16:9"
android:textColor="@android:color/white"
android:textSize="@dimen/ts_20" />
<TextView
android:id="@+id/play_speed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/vs_10"
android:layout_marginRight="@dimen/vs_10"
android:background="@drawable/button_dialog_main"
android:padding="@dimen/vs_10"
android:text="x1.0"
android:textColor="@android:color/white"
android:textSize="@dimen/ts_20" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/vs_10"
android:layout_marginRight="@dimen/vs_10"
android:padding="@dimen/vs_10"
android:text="片头片尾"
android:textColor="@color/color_CC000000"
android:textSize="@dimen/ts_20" />
<TextView
android:id="@+id/play_time_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/vs_10"
android:layout_marginRight="@dimen/vs_10"
android:background="@drawable/button_dialog_main"
android:padding="@dimen/vs_10"
android:text="01:00"
android:textColor="@android:color/white"
android:textSize="@dimen/ts_20" />
<TextView
android:id="@+id/play_time_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/vs_10"
android:layout_marginRight="@dimen/vs_10"
android:background="@drawable/button_dialog_main"
android:padding="@dimen/vs_10"
android:text="01:00"
android:textColor="@android:color/white"
android:textSize="@dimen/ts_20" />
<TextView
android:id="@+id/play_time_step"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/vs_10"
android:layout_marginRight="@dimen/vs_10"
android:background="@drawable/button_dialog_main"
android:padding="@dimen/vs_10"
android:text="1S"
android:textColor="@android:color/white"
android:textSize="@dimen/ts_20" />
</LinearLayout>
<com.owen.tvrecyclerview.widget.TvRecyclerView
android:id="@+id/mGridViewWord"
android:layout_width="match_parent"
android:layout_height="@dimen/vs_50"
android:layout_marginTop="@dimen/vs_10"
android:layout_marginBottom="@dimen/vs_10"
android:clipChildren="false"
android:clipToPadding="false"
android:visibility="gone"
app:tv_horizontalSpacingWithMargins="@dimen/vs_5"
app:tv_selectedItemIsCentered="true"
app:tv_verticalSpacingWithMargins="@dimen/vs_5" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/vs_10"
android:orientation="horizontal">
<TextView
android:id="@+id/curr_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="@dimen/vs_10"
android:paddingRight="@dimen/vs_10"
android:text="00:00"
android:textColor="@color/color_CC000000"
android:textSize="@dimen/ts_20" />
<SeekBar
android:id="@+id/seekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:background="@null"
android:focusable="false"
android:focusableInTouchMode="false"
android:max="1000"
android:maxHeight="@dimen/vs_6"
android:minHeight="@dimen/vs_6"
android:padding="@dimen/vs_0"
android:paddingStart="@dimen/vs_0"
android:paddingEnd="@dimen/vs_0"
android:progressDrawable="@drawable/shape_player_control_vod_seek"
android:thumb="@drawable/shape_player_control_vod_seek_thumb"
android:thumbOffset="@dimen/vs_0" />
<TextView
android:id="@+id/total_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="@dimen/vs_10"
android:paddingLeft="@dimen/vs_10"
android:text="00:00"
android:textColor="@color/color_CC000000"
android:textSize="@dimen/ts_20" />
</LinearLayout>
</LinearLayout>
<FrameLayout
android:id="@+id/tv_pause_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:tag="vod_control_pause"
android:visibility="gone"
tools:visibility="visible">
<TextView
android:id="@+id/tv_info_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:text="http://"
android:textColor="@android:color/white"
android:textSize="@dimen/ts_24" />
<LinearLayout
android:layout_width="@dimen/vs_280"
android:layout_height="@dimen/vs_200"
android:layout_gravity="center"
android:background="@drawable/shape_user_focus"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="@dimen/vs_60"
android:layout_height="@dimen/vs_60"
android:layout_gravity="center"
android:focusable="false"
android:focusableInTouchMode="false"
android:src="@drawable/icon_play" />
<TextView
android:id="@+id/tv_pause_progress_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="@dimen/vs_20"
android:focusable="false"
android:focusableInTouchMode="false"
android:tag="vod_control_pause_t"
android:textColor="@android:color/white"
android:textSize="@dimen/ts_30"
tools:text="100" />
</LinearLayout>
</FrameLayout>
<TextView
android:id="@+id/tv_slide_progress_text"
android:layout_width="@dimen/vs_200"
android:layout_height="@dimen/vs_100"
android:layout_gravity="center"
android:background="@drawable/shape_user_focus"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="center"
android:tag="vod_control_slide_info"
android:textAlignment="gravity"
android:textColor="@android:color/white"
android:textSize="@dimen/ts_30"
android:visibility="gone"
tools:text="100" />
<LinearLayout
android:id="@+id/tv_progress_container"
android:layout_width="@dimen/vs_280"
android:layout_height="@dimen/vs_200"
android:layout_gravity="center"
android:background="@drawable/shape_user_focus"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<ImageView
android:id="@+id/tv_progress_icon"
android:layout_width="@dimen/vs_60"
android:layout_height="@dimen/vs_60"
android:focusable="false"
android:focusableInTouchMode="false"
tools:src="@drawable/icon_back" />
<TextView
android:id="@+id/tv_progress_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="@dimen/vs_20"
android:focusable="false"
android:focusableInTouchMode="false"
android:textColor="@android:color/white"
android:textSize="@dimen/ts_30"
tools:text="100" />
</LinearLayout>
<ProgressBar
android:layout_width="@dimen/vs_50"
android:layout_height="@dimen/vs_50"
android:layout_gravity="center"
android:indeterminateBehavior="repeat"
android:indeterminateDrawable="@drawable/anim_loading"
android:indeterminateOnly="true"
android:tag="vod_control_loading" />
</FrameLayout>
Loading…
Cancel
Save