我有一个带有多个视图的RecyclerView。其中一个视图具有“播放”按钮和“搜索栏”,用于播放音频文件。最佳做法是,您是否在AudioViewHolder中实现ExoPlayer?还是在RecyclerView所在的活动中?
如果我在Activity中实现它,则在单击Activity上的Play / Pause按钮时,将从AudioViewHolder(适配器中的接口)发送回叫。 ExoPlayer.onPlayerStateChanged(STATE_ENDED)将无法访问“播放按钮视图”并更新按钮图像。
如何将ExoPlayer发送到AudioViewHolder,以便更新播放/暂停按钮的图像?
AudioChatItem
private void initPlayButton(File file) {
playButton.requestFocus();
playButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (isPlaying) {
isPlaying = false;
playButton.setImageResource(R.drawable.ic_play);
audioControllerCallback.onStop();
} else {
isPlaying = true;
playButton.setImageResource(R.drawable.ic_stop);
audioControllerCallback.onPlay(file);
}
}
});
}
ChatActivity
private ChatMessagesAdapter.AudioControllerCallback audioControllerCallback = new ChatMessagesAdapter.AudioControllerCallback() {
@Override
public void onPlay(File file) {
prepareExoPlayerFromUri(Uri.parse(file.getAbsolutePath()));
mExoPlayer.setPlayWhenReady(true);
}
@Override
public void onStop() {
mExoPlayer.setPlayWhenReady(false);
}
@Override
public void onSeek(int progress) {
mExoPlayer.seekTo(progress * 1000);
}
};
private Player.EventListener eventListener = new Player.EventListener() {
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
Log.i("EXO", "onPlayerStateChanged: playWhenReady = " + String.valueOf(playWhenReady)
+ " playbackState = " + playbackState);
switch (playbackState) {
case Player.STATE_ENDED:
Log.i("EXO", "Playback ended!");
//Here I need to access the playButton in my ViewHolder
audioControllerCallback.onStop();
mExoPlayer.seekTo(0);
break;
case Player.STATE_READY:
Log.i("EXO", "ExoPlayer ready! pos: " + mExoPlayer.getCurrentPosition()
+ " max: " + stringForTime((int) mExoPlayer.getDuration()));
// setProgress();
break;
case Player.STATE_BUFFERING:
Log.i("EXO", "Playback buffering!");
break;
case Player.STATE_IDLE:
Log.i("EXO", "ExoPlayer idle!");
break;
}
}
...
}
答案 0 :(得分:0)
Pode ser na活动。 哦,法蒂奥·法诺·塞斯迪奥·罗达·瓦里奥斯·阿迪奥斯·梅斯莫·速度,康考达?
它可能在“活动”中。 事实是,同时运行多个音频没有意义,您同意吗?
public class StepDetailFragment extends Fragment implements StepsViewModel.PlayerLifeCycle,
StepsViewModel.StepsEventHandler {
public static final String STEP_SELECTED = StepDetailFragment.class.getName().concat(".STEP_SELECTED");
private static final String PLAYER_STATE = StepDetailFragment.class.getName().concat(".PLAYER_STATE");
private FragmentStepsDetailBinding mBinding;
private StepsViewModel mViewModel;
private ExoPlayer mExoPlayer;
private MediaSessionCompat mMediaSession;
private PlaybackStateCompat.Builder mStateBuilder;
private Long mPlayerPosition;
public StepDetailFragment(){}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_steps_detail, container,
false);
if(getActivity() != null)
mViewModel = StepsDetailsActivity.obtainViewModel(getActivity());
return mBinding.getRoot();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
if (getArguments().containsKey(STEP_SELECTED)) {
Step mCurrentStep = getArguments().getParcelable(STEP_SELECTED);
if (mViewModel != null){
mViewModel.getCurrentStep().setValue(mCurrentStep);
}
}
}
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if(getActivity() != null && mViewModel == null)
mViewModel = StepsDetailsActivity.obtainViewModel(getActivity());
mViewModel.setPlayerLifeCycle(this);
mViewModel.setStepsEventHandler(this);
mBinding.setViewModel(mViewModel);
mBinding.setEventHandler(new WeakReference<StepsViewModel.StepsEventHandler>(this));
if (getArguments() != null) {
if (getArguments().containsKey(STEP_SELECTED)) {
Step mCurrentStep = getArguments().getParcelable(STEP_SELECTED);
mViewModel.getCurrentStep().setValue(mCurrentStep);
}
}
if (savedInstanceState != null) {
if (savedInstanceState.containsKey(STEP_SELECTED)) {
Step mCurrentStep = savedInstanceState.getParcelable(STEP_SELECTED);
mViewModel.getCurrentStep().setValue(mCurrentStep);
}
if (savedInstanceState.containsKey(PLAYER_STATE)) {
mPlayerPosition = savedInstanceState.getLong(PLAYER_STATE);
}
}
mViewModel.getCurrentStep().observe(this, new Observer<Step>() {
@Override
public void onChanged(@Nullable Step step) {
if (step != null) {
mBinding.setViewModel(mViewModel);
mBinding.setEventHandler(new WeakReference<StepsViewModel.StepsEventHandler>(
StepDetailFragment.this));
setupToolbar();
releasePlayer();
}
}
});
setupToolbar();
}
private void setupToolbar() {
if (mViewModel.getCurrentStep().getValue() != null) {
AppCompatActivity activity = (AppCompatActivity) this.getActivity();
if (activity != null) {
activity.setTitle(mViewModel.getCurrentStep().getValue().getShortDescription());
}
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(STEP_SELECTED, mViewModel.getCurrentStep().getValue());
if (mExoPlayer != null) {
outState.putLong(PLAYER_STATE, mExoPlayer.getCurrentPosition());
}
}
@Override
public void onDetach() {
super.onDetach();
releasePlayer();
}
@Override
public void onSetupPlayer(SimpleExoPlayer exoPlayer) {
if (isAdded()) {
mExoPlayer = exoPlayer;
mExoPlayer.addListener(new MyPlayerListener());
if (mMediaSession == null) {
initializeMediaSession();
}
if (mPlayerPosition != null) {
mExoPlayer.seekTo(mPlayerPosition);
mPlayerPosition = null;
}
}
}
@Override
public void nextPositionClick() {
mViewModel.nextStep();
}
@Override
public void previousPositionClick() {
mViewModel.prevStep();
}
private class MyPlayerListener implements Player.EventListener {
@Override
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) { }
@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { }
@Override
public void onLoadingChanged(boolean isLoading) { }
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if (mExoPlayer != null) {
if ((playbackState == Player.STATE_READY) && playWhenReady) {
mStateBuilder.setState(PlaybackStateCompat.STATE_PLAYING,
mExoPlayer.getCurrentPosition(), 1f);
} else if ((playbackState == Player.STATE_READY)) {
mStateBuilder.setState(PlaybackStateCompat.STATE_PAUSED,
mExoPlayer.getCurrentPosition(), 1f);
}
mMediaSession.setPlaybackState(mStateBuilder.build());
}
}
@Override
public void onRepeatModeChanged(int repeatMode) { }
@Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) { }
@Override
public void onPlayerError(ExoPlaybackException error) { }
@Override
public void onPositionDiscontinuity(int reason) { }
@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) { }
@Override
public void onSeekProcessed() { }
}
private void initializeMediaSession() {
if (getContext() != null) {
mMediaSession = new MediaSessionCompat(getContext(), this.getClass().getSimpleName());
mMediaSession.setFlags(
MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mMediaSession.setMediaButtonReceiver(null);
mStateBuilder = new PlaybackStateCompat.Builder()
.setActions(
PlaybackStateCompat.ACTION_PLAY |
PlaybackStateCompat.ACTION_PAUSE |
PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS |
PlaybackStateCompat.ACTION_PLAY_PAUSE);
mMediaSession.setPlaybackState(mStateBuilder.build());
mMediaSession.setCallback(new MySessionCallback());
mMediaSession.setActive(true);
}
}
private class MySessionCallback extends MediaSessionCompat.Callback {
@Override
public void onPlay() {
if (mExoPlayer != null) {
mExoPlayer.setPlayWhenReady(true);
}
}
@Override
public void onPause() {
if (mExoPlayer != null) {
mExoPlayer.setPlayWhenReady(false);
}
}
@Override
public void onSkipToPrevious() {
if (mExoPlayer != null) {
mExoPlayer.seekTo(0);
}
}
}
private void releasePlayer() {
if (mExoPlayer != null) {
mExoPlayer.stop();
mExoPlayer.release();
}
mExoPlayer = null;
}
}