package com.wasu.cs.widget.mediacontrol; import android.annotation.SuppressLint; import android.content.Context; import android.media.MediaPlayer; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.LayoutInflater; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; import com.wasu.module.log.WLog; import java.util.ArrayList; import java.util.Formatter; import java.util.List; import java.util.Locale; import cn.com.wasu.main.R; /** * seek控制条 */ @SuppressLint("NewApi") public class SeekbarController extends FrameLayout implements IMediaControllerChildView, OnSeekBarChangeListener { /** * seekbar加减幅度默认30s */ private static int INCREMENT = 30000; private static float INCREMENT_DELTA = 1.0f; private MediaController mediaController; private TextView startPoint; private TextView totalDuration; private TextView currentDuration; private SeekBar seekbar; private ImageView seekIndicator; /** * 允许seek的最大时间 */ private int limitTime = Integer.MAX_VALUE; public int getLimitTime() { return limitTime; } public void setLimitTime(int limitTime) { this.limitTime = limitTime; } /** * seekBar的宽度 * */ private int mSeekBarWidth = -1; /** * seekBar起点x坐标 */ private float startX; /** * 用户是否正在seek */ private boolean isSeeking; /** * 播放器是否正在执行seek操作 */ private boolean isPreformSeeking; /** * 根据用户seek进度,更新seekbar和currentDuration */ private Runnable seekTask = new Runnable() { @Override public void run() { if (!mediaController.getPlayer().isInPlaybackState()) { return; } INCREMENT_DELTA = 1.0f; setSeekIndicatorVisible(false); mediaController.getPlayer().seekTo(seekbar.getProgress()); isSeeking = false; } }; public SeekbarController(Context context) { super(context); init(context); } public SeekbarController(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public SeekbarController(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } private void init(Context context) { setId(MediaController.generateID()); LayoutInflater.from(context).inflate(R.layout.media_controller_seekbar, this); startPoint = (TextView) findViewById(R.id.start_point); startPoint.setText("00:00:00"); totalDuration = (TextView) findViewById(R.id.total_duration); currentDuration = (TextView) findViewById(R.id.current_duration); seekbar = (SeekBar) findViewById(R.id.seekbar); seekIndicator = (ImageView) findViewById(R.id.seek_indicator); startX = seekbar.getLeft() + seekbar.getPaddingLeft(); currentDuration.setTranslationX(startX); } private void setSeekIndicatorVisible(boolean isShow) { seekIndicator.setVisibility(isShow ? VISIBLE : INVISIBLE); } protected void resetSeekIndicatorToPause(){ seekIndicator.setImageResource(R.drawable.media_controller_seekbar_pause_indicator); } @Override public boolean isAutoHide() { return true; } @Override public void onShow(final MediaController mediaController) { this.mediaController = mediaController; final int duration = mediaController.getPlayer().getDuration(); final int currDuration = mediaController.getPlayer().getCurrentPosition(); if (duration <= INCREMENT) { INCREMENT = duration / 10; } else { INCREMENT = 30000; } seekbar.setOnSeekBarChangeListener(this); currentDuration.setText(convertTimeMills2Str(currDuration)); totalDuration.setText(convertTimeMills2Str(duration)); seekbar.setMax(duration); seekbar.setKeyProgressIncrement(INCREMENT); seekbar.setProgress(currDuration); if (mSeekBarWidth < 0){ seekbar.post(new Runnable() { @Override public void run() { mSeekBarWidth =seekbar.getMeasuredWidth(); onProgressChanged(seekbar, currDuration, false); } });}else { onProgressChanged(seekbar, currDuration, false); } setSeekIndicatorVisible(!mediaController.getPlayer().isPlaying()); } @Override public void onHide(MediaController mediaController) { seekbar.setOnSeekBarChangeListener(null); } @Override public boolean onShield(KeyEvent event) { boolean ret = false; if (event.getAction() == KeyEvent.ACTION_DOWN) { int progress = seekbar.getProgress(); switch (event.getKeyCode()) { case KeyEvent.KEYCODE_DPAD_UP: case KeyEvent.KEYCODE_DPAD_DOWN: case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_DOWN: case KeyEvent.KEYCODE_VOLUME_MUTE: case KeyEvent.KEYCODE_MENU: // 2017/1/20 Add By Frewen.Wong 放SeekBar显示时候屏蔽其他按钮的功能 //ret = true; //break; case KeyEvent.KEYCODE_DPAD_CENTER: case KeyEvent.KEYCODE_ENTER: ret = false; break; case KeyEvent.KEYCODE_BACK: break; case KeyEvent.KEYCODE_DPAD_LEFT: if (seekbar.getMax() < INCREMENT) { break; } seekIndicator.setImageResource(R.drawable.media_controller_seekbar_back_indicator); isSeeking = true; INCREMENT_DELTA *= 1.1f; setSeekIndicatorVisible(true); removeCallbacks(seekTask); progress -= INCREMENT * INCREMENT_DELTA; if (progress < 0) { progress = 0; } seekbar.setProgress(progress); currentDuration.setText(convertTimeMills2Str(progress)); postDelayed(seekTask, 500); ret = true; break; case KeyEvent.KEYCODE_DPAD_RIGHT: if (seekbar.getMax() < INCREMENT) { break; } seekIndicator.setImageResource(R.drawable.media_controller_seekbar_forward_indicator); isSeeking = true; INCREMENT_DELTA *= 1.1f; setSeekIndicatorVisible(true); removeCallbacks(seekTask); progress += INCREMENT * INCREMENT_DELTA; if (progress > limitTime) { progress = limitTime; } if (progress > seekbar.getMax()) { progress = seekbar.getMax(); } seekbar.setProgress(progress); currentDuration.setText(convertTimeMills2Str(progress)); postDelayed(seekTask, 500); ret = true; break; default: ret = true; break; } } return ret; } @Override public void clear() { limitTime = Integer.MAX_VALUE; isSeeking = false; isPreformSeeking = false; removeCallbacks(seekTask); } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { float halfTextWidth = currentDuration.getMeasuredWidth() / 2.f; float seekbarWidth = mSeekBarWidth - seekbar.getPaddingLeft() - seekbar.getPaddingRight(); float position = progress * 1.f / seekbar.getMax() * 1.f * seekbarWidth; position += startX; if (position <= halfTextWidth) { position = startX; } else if (position > halfTextWidth && position < mSeekBarWidth - halfTextWidth) { position = position - halfTextWidth; } else { position = startX + seekbarWidth; } currentDuration.setTranslationX(position); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } private String convertTimeMills2Str(int timeMs) { int totalSeconds = (int) (timeMs / 1000.f); int seconds = (int) (totalSeconds % 60.f); int minutes = (int) ((totalSeconds / 60.f) % 60.f); int hours = (int) (totalSeconds / 3600.f); StringBuilder sb = new StringBuilder(); Formatter ft = new Formatter(sb, Locale.getDefault()); String ret = ""; sb.setLength(0); if (hours > 0) { ret = ft.format("%d:%02d:%02d", hours, minutes, seconds).toString(); ft.close(); return ret; } else { ret = ft.format("%02d:%02d", minutes, seconds).toString(); ft.close(); return ret; } } @Override public void onAdStatusChanged(int arg0, int arg1) { // TODO Auto-generated method stub } @Override public void onCompletion(MediaPlayer arg0) { // TODO Auto-generated method stub } @Override public void onError(MediaPlayer arg0, int arg1, int arg2) { // TODO Auto-generated method stub } @Override public void onInfo(MediaPlayer arg0, int arg1, int arg2) { // TODO Auto-generated method stub } @Override public void onPause(MediaPlayer arg0) { seekIndicator.setImageResource(R.drawable.media_controller_seekbar_pause_indicator); } @Override public void onPrepareComplete(MediaPlayer arg0) { // TODO Auto-generated method stub } @Override public void onPreparing(MediaPlayer arg0) { // TODO Auto-generated method stub } @Override public void onProgress(int arg0, int arg1, int arg2) { if (isSeeking || isPreformSeeking || seekbar.getMax() == 100) { return; } int currDuration = mediaController.getPlayer().getCurrentPosition(); seekbar.setProgress(currDuration); currentDuration.setText(convertTimeMills2Str(currDuration)); } @Override public void onResume(MediaPlayer arg0) { // TODO Auto-generated method stub } @Override public void onSeekComplete(MediaPlayer arg0) { isPreformSeeking = false; } @Override public void onSeeking(MediaPlayer arg0) { isPreformSeeking = true; } @Override public void onStart(MediaPlayer arg0) { // TODO Auto-generated method stub } @Override public void onStatusChanged(MediaPlayer arg0, int arg1) { // TODO Auto-generated method stub } @Override public void onStop(MediaPlayer arg0) { // TODO Auto-generated method stub } @Override public void onWasuError(int arg0, String arg1) { // TODO Auto-generated method stub } @Override public void onWasuPlayLimit(int arg0, String arg1) { } private List> relativeViews = new ArrayList>(); @Override public void setRelativeViews(IMediaControllerChildView... views) { for (IMediaControllerChildView v : views) { if (!relativeViews.contains(v)) { relativeViews.add(v); } } } @Override public List> getRelativeViews() { return relativeViews; } }