我有一个视频源(类似于 TikTok),但是当我向上滑动新视频时,旧视频仍在播放。我设法获得了一个页面监听器,但我无法从“家庭 fragment ”控制 ExoPlayer。
关于如何从 Home Fragment 触发 RecyclerView 适配器内部的东西的任何想法?
如果有更好的解决方案,请告诉我。
首页 fragment
public class HomeFragment extends Fragment {
private View view;
RecyclerView recyclerView;
List<Model> models = new ArrayList<>();
MainRecylerAdapter adapter;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_home, container, false);
recyclerView = view.findViewById(R.id.recyclerview);
models.add(new Model(1, "https://www.newslistener.com/Mukesh/1.mp4", "one"));
models.add(new Model(2, "https://www.newslistener.com/Mukesh/2.mp4", "one"));
models.add(new Model(3, "https://www.newslistener.com/Mukesh/3.mp4", "one"));
models.add(new Model(4, "https://www.newslistener.com/Mukesh/4.mp4", "one"));
models.add(new Model(5, "https://www.newslistener.com/Mukesh/5.mp4", "one"));
models.add(new Model(6, "https://www.newslistener.com/Mukesh/6.mp4", "one"));
models.add(new Model(7, "https://www.newslistener.com/Mukesh/7.mp4", "one"));
models.add(new Model(8, "https://www.newslistener.com/Mukesh/8.mp4", "one"));
models.add(new Model(9, "https://www.newslistener.com/Mukesh/9.mp4", "one"));
models.add(new Model(10, "https://www.newslistener.com/Mukesh/10.mp4", "one"));
models.add(new Model(11, "https://www.newslistener.com/Mukesh/11.mp4", "one"));
models.add(new Model(12, "https://www.newslistener.com/Mukesh/12.mp4", "one"));
models.add(new Model(13, "https://www.newslistener.com/Mukesh/13.mp4", "one"));
models.add(new Model(14, "https://www.newslistener.com/Mukesh/14.mp4", "one"));
models.add(new Model(15, "https://www.newslistener.com/Mukesh/15.mp4", "one"));
models.add(new Model(16, "https://www.newslistener.com/Mukesh/16.mp4", "one"));
models.add(new Model(17, "https://www.newslistener.com/Mukesh/17.mp4", "one"));
models.add(new Model(18, "https://www.newslistener.com/Mukesh/18.mp4", "one"));
models.add(new Model(19, "https://www.newslistener.com/Mukesh/19.mp4", "one"));
models.add(new Model(20, "https://www.newslistener.com/Mukesh/20.mp4", "one"));
models.add(new Model(21, "https://www.newslistener.com/Mukesh/21.mp4", "one"));
models.add(new Model(22, "https://www.newslistener.com/Mukesh/22.mp4", "one"));
models.add(new Model(23, "https://www.newslistener.com/Mukesh/23.mp4", "one"));
models.add(new Model(24, "https://www.newslistener.com/Mukesh/24.mp4", "one"));
models.add(new Model(25, "https://www.newslistener.com/Mukesh/25.mp4", "one"));
models.add(new Model(26, "https://www.newslistener.com/Mukesh/26.mp4", "one"));
models.add(new Model(27, "https://www.newslistener.com/Mukesh/27.mp4", "one"));
models.add(new Model(28, "https://www.newslistener.com/Mukesh/28.mp4", "one"));
models.add(new Model(29, "https://www.newslistener.com/Mukesh/29.mp4", "one"));
models.add(new Model(30, "https://www.newslistener.com/Mukesh/30.mp4", "one"));
models.add(new Model(31, "https://www.newslistener.com/Mukesh/31.mp4", "one"));
models.add(new Model(32, "https://www.newslistener.com/Mukesh/32.mp4", "one"));
models.add(new Model(33, "https://www.newslistener.com/Mukesh/33.mp4", "one"));
models.add(new Model(34, "https://www.newslistener.com/Mukesh/34.mp4", "one"));
models.add(new Model(35, "https://www.newslistener.com/Mukesh/35.mp4", "one"));
SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
adapter = new MainRecylerAdapter(models, getActivity());
recyclerView.setAdapter(adapter);
return view;
}
}
适配器 public class MainRecylerAdapter extends RecyclerView.Adapter<MainRecylerAdapter.ViewHolder> {
List<Model> models = new ArrayList<>();
Context context;
private int index = 0;
public MainRecylerAdapter(List<Model> models, Context context) {
this.models = models;
this.context = context;
}
@NonNull
@Override
public MainRecylerAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_recyler_layout, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final MainRecylerAdapter.ViewHolder holder, final int position) {
if (holder.isPlaying()) {
Log.e("TAG1", "play");
holder.releasePlayer();
holder.intiPlayer(models.get(position).getUrl());
} else {
Log.e("TAG1", "empty");
holder.intiPlayer(models.get(position).getUrl());
}
}
@Override
public int getItemCount() {
return models.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
SimpleExoPlayerView exoPlayerView;
SimpleExoPlayer exoPlayer;
private long playbackPosition;
private int currentWindow;
private boolean playWhenReady;
ProgressBar progressBar;
public ViewHolder(@NonNull View itemView) {
super(itemView);
exoPlayerView = itemView.findViewById(R.id.exoplayerview);
progressBar = itemView.findViewById(R.id.progress);
}
private void intiPlayer(String url) {
try {
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelector trackSelector = new DefaultTrackSelector(new AdaptiveTrackSelection.Factory(bandwidthMeter));
exoPlayer = ExoPlayerFactory.newSimpleInstance(context, trackSelector);
Uri videoURI = Uri.parse(url);
DefaultHttpDataSourceFactory dataSourceFactory = new DefaultHttpDataSourceFactory("exoplayer_video");
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
MediaSource mediaSource = new ExtractorMediaSource(videoURI, dataSourceFactory, extractorsFactory, null, null);
exoPlayerView.setPlayer(exoPlayer);
exoPlayer.prepare(mediaSource);
exoPlayer.setPlayWhenReady(true);
} catch (Exception e) {
Log.e("MainAcvtivity", " exoplayer error " + e.toString());
}
}
private boolean isPlaying() {
return exoPlayer != null
&& exoPlayer.getPlaybackState() != Player.STATE_ENDED
&& exoPlayer.getPlaybackState() != Player.STATE_IDLE
&& exoPlayer.getPlayWhenReady();
}
private void releasePlayer() {
if (exoPlayer != null) {
playbackPosition = exoPlayer.getCurrentPosition();
currentWindow = exoPlayer.getCurrentWindowIndex();
playWhenReady = exoPlayer.getPlayWhenReady();
exoPlayer.release();
exoPlayer = null;
}
}
}
最佳答案
这是一个要实现的新概念,因此请查看将 RecyclerView 与 ExoPlayer 集成 — 干净的方式 — 和自定义,我的解决方案基于该 article
P.S 对于更简洁的代码,我们将使用数据绑定(bind)库和 BindingAdapter,所以不要忘记在 gradle 中启用它们。
让我们创建一个带有 @BindingAdapter 注释的扩展函数,我们将使用它来设置我们的 PlayerView,并将我们在 xml 文件中传递的值作为参数。
BindingData 适配器将是这样的
@BindingAdapter("video_url", "on_state_change")
fun PlayerView.loadVideo(url: String, callback: PlayerStateChange) {
if (url == null) return
val player = ExoPlayerFactory.newSimpleInstance(
context, DefaultRenderersFactory(context), DefaultTrackSelector(),
DefaultLoadControl()
)
player.playWhenReady = true
player.repeatMode = Player.REPEAT_MODE_ALL
// When changing track, retain the latest frame instead of showing a black screen
setKeepContentOnPlayerReset(true)
// We'll show the controller
this.useController = true
// Provide url to load the video from here
val mediaSource = ExtractorMediaSource.Factory(
DefaultHttpDataSourceFactory("Demo")
).createMediaSource(Uri.parse(url))
player.prepare(mediaSource)
this.player = player
this.player!!.addListener(object : Player.EventListener {
override fun onPlayerError(error: ExoPlaybackException?) {
super.onPlayerError(error)
this@loadVideo.context.toast("Oops! Error occurred while playing media.")
}
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
super.onPlayerStateChanged(playWhenReady, playbackState)
if (playbackState == Player.STATE_BUFFERING) callback.onVideoBuffering(player) // Buffering.. set progress bar visible here
if (playbackState == Player.STATE_READY){
// [PlayerView] has fetched the video duration so this is the block to hide the buffering progress bar
callback.onVideoDurationRetrieved(this@loadVideo.player.duration, player)
}
if (playbackState == Player.STATE_READY && player.playWhenReady){
// [PlayerView] has started playing/resumed the video
callback.onStartedPlaying(player)
}
}
})
}
您可以从 here 访问演示 repovia GIPHY
关于java - 带有 Recyclerview 的 Exoplayer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61455134/