Last active
November 3, 2015 10:49
-
-
Save Folyd/1463b391d133ded157e1 to your computer and use it in GitHub Desktop.
A sample project to explain this issue clear.https://code.google.com/p/android/issues/detail?id=192551&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.Context; | |
import android.util.AttributeSet; | |
import android.view.KeyEvent; | |
import android.widget.SeekBar; | |
/** | |
* This is workaround version for SeekBar which didn't detect the progress changed | |
* by arrow key pressed. | |
* | |
*/ | |
public class KeySensitiveSeekBar extends SeekBar { | |
private OnKeyProgressChangeListener mOnKeyProgressChangeListener; | |
public KeySensitiveSeekBar(Context context) { | |
super(context); | |
} | |
public KeySensitiveSeekBar(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
} | |
public KeySensitiveSeekBar(Context context, AttributeSet attrs, int defStyleAttr) { | |
super(context, attrs, defStyleAttr); | |
} | |
@Override | |
public boolean onKeyDown(int keyCode, KeyEvent event) { | |
if (isEnabled()) { | |
int increment = getKeyProgressIncrement(); | |
switch (keyCode) { | |
case KeyEvent.KEYCODE_DPAD_LEFT: | |
increment = -increment; | |
// fallthrough | |
case KeyEvent.KEYCODE_DPAD_RIGHT: | |
// Let progress bar handle clamping values. | |
setProgress(getProgress() + increment); | |
onKeyChange(); | |
return true; | |
} | |
} | |
return true; | |
} | |
/** | |
* A hook method for arrow key pressed. | |
*/ | |
protected void onKeyChange() { | |
if (mOnKeyProgressChangeListener != null) { | |
mOnKeyProgressChangeListener.onKeyProgressChange(this); | |
} | |
} | |
public void setOnKeyProgressChangeListener(OnKeyProgressChangeListener listener) { | |
mOnKeyProgressChangeListener = listener; | |
} | |
/** | |
* A callback to indicate the progress changed by arrow key pressed. | |
*/ | |
public interface OnKeyProgressChangeListener { | |
void onKeyProgressChange(SeekBar seekBar); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class MediaController extends FrameLayout implements OnClickListener { | |
private ImageButton mPlayButton; | |
private TextView mCurrentTime; | |
private TextView mTotalTime; | |
private KeySensitiveSeekBar mSeekBar; | |
private IMediaPlayer mPlayer; | |
private SimpleDateFormat mDateFormat; | |
private static final int SHOW_PROGRESS = 0; | |
private static final int SEEK_BY_USER = 1; | |
private static final int PLAY_AGAIN = 2; | |
public MediaController(Context context) { | |
super(context); | |
initialize(context); | |
} | |
public MediaController(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
initialize(context); | |
} | |
public MediaController(Context context, AttributeSet attrs, int defStyle) { | |
super(context, attrs, defStyle); | |
initialize(context); | |
} | |
private void initialize(Context context) { | |
LayoutInflater layoutInflater = LayoutInflater.from(context); | |
layoutInflater.inflate(R.layout.layout_media_controller, this, true); | |
mPlayButton = (ImageButton) findViewById(R.id.video_play_btn); | |
mPlayButton.setOnClickListener(this); | |
mCurrentTime = (TextView) findViewById(R.id.video_current_time); | |
mTotalTime = (TextView) findViewById(R.id.video_total_time); | |
mSeekBar = (KeySensitiveSeekBar) findViewById(R.id.video_seek_bar); | |
mSeekBar.setOnSeekBarChangeListener(mOnSeekBarChangeListener); | |
mSeekBar.setOnKeyProgressChangeListener(mOnKeyProgressChangeListener); | |
mDateFormat = new SimpleDateFormat("mm:ss"); | |
} | |
public void setMediaPlayer(IMediaPlayer mediaPlayer) { | |
mPlayer = mediaPlayer; | |
} | |
private Handler mSeekBarHandler = new Handler(new Handler.Callback() { | |
@Override | |
public boolean handleMessage(Message msg) { | |
int progress; | |
switch (msg.what) { | |
case SHOW_PROGRESS: | |
// show progress... | |
break; | |
case SEEK_BY_USER: | |
//Seek by user... | |
break; | |
case PLAY_AGAIN: | |
//Play again... | |
break; | |
} | |
return true; | |
} | |
}); | |
private final OnSeekBarChangeListener mOnSeekBarChangeListener = new OnSeekBarChangeListener() { | |
@Override | |
public void onStopTrackingTouch(SeekBar seekBar) { | |
mSeekBarHandler.sendEmptyMessage(SHOW_PROGRESS); | |
if (mPlayer != null) { | |
mPlayer.seekTo(seekBar.getProgress()); | |
} | |
mSeekBarHandler.sendEmptyMessage(SEEK_BY_USER); | |
} | |
@Override | |
public void onStartTrackingTouch(SeekBar seekBar) { | |
mSeekBarHandler.removeMessages(SHOW_PROGRESS); | |
} | |
@Override | |
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { | |
if (fromUser) { | |
mPlayer.seekTo(progress); | |
mSeekBarHandler.sendEmptyMessage(SEEK_BY_USER); | |
} | |
} | |
}; | |
private final OnKeyProgressChangeListener mOnKeyProgressChangeListener = new OnKeyProgressChangeListener() { | |
@Override | |
public void onKeyProgressChange(SeekBar seekBar) { | |
if (mOnSeekBarChangeListener != null) { | |
mOnSeekBarChangeListener.onProgressChanged(seekBar, seekBar.getProgress(), true); | |
} | |
} | |
}; | |
//Other methods omitted... | |
public interface IMediaPlayer { | |
void start(); | |
void pause(); | |
int getDuration(); | |
int getCurrentPosition(); | |
void seekTo(int pos); | |
boolean isPlaying(); | |
void progressCallback(int progress); | |
} | |
} |
KeySensitiveSeekBar
and MediaController
is my sample project.KeySensitiveSeekBar
is my workaround solution to explain the problem. 😄
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I wanna to build a custom
MediaController
which can support forward and backward video progress by pressed arrow key,such asKEYCODE_DPAD_LEFT
andKEYCODE_DPAD_RIGHT
,althoughandroid.widget.AbsSeekBar
handle this inonKeyDown()
method,(here isAbsSeekBar
source code,target api 23 )SeekBar
never overrideonKeyChange()
method to notify the progress change by callOnSeekBarChangeListener.onProgressChanged()
.The interesting thing is,
RatingBar
override the method,and callmOnRatingBarChangeListener.onRatingChanged()
method to notify the progress change.