無縫續播這裏不作講解(其實我也不會呀...),作過播放器的應該都懂吧,原理大體就是:git
解碼器動態關聯不一樣的渲染視圖(RenderView),好比使用MediaPlayer動態關聯SurfaceView,就如同一個電腦主機不斷鏈接不一樣的顯示器。
複製代碼
PS:這裏注意一下,render不要重置,否則會閃屏哦github
Demo中用的是這個播放器 PlayerBase,高度解耦(不像其餘播放器同樣,對佈局文件有限制),支持各類自定義,最大的好處的就是提供能無縫續播助手(續播的話不要使用mediaPlayer,會出現問題)。 bash
這裏仍是簡單說下播放器怎麼用吧,不須要改界面的話(demo中略微作了修改),直接拷下面紅色方框中的類,在Application裏面進行配置就可使用啦(ijk,exo須要引入對應的庫哦,demo中ijk不支持https,因此視頻可能不能播放)。 網絡
AssistPlayer.get().play(mContainer, null);
複製代碼
就能夠在不一樣的容器內(即上面的mContainer)繼續播放以前的內容了。 須要自定義界面或者有其餘問題的參考這裏和demo,有問題的加羣問羣主吧。ide
用RecyclerView實現,這裏說一下頁面滑動對視頻item的處理:當頁面中止滑動後,判斷是屏幕中央是否有可見的視頻item,有則開始播放。同時,判斷以前是否有在播放的視頻滑出了界面,有則中止播放。佈局
//僞代碼
if (newState == SCROLL_STATE_IDLE) {
//滑動屏幕中間開始
LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager();
int first = manager.findFirstVisibleItemPosition();
int last = manager.findLastVisibleItemPosition();
for (int i = first; i <= last; i++) {
if (isVideo) {
//列表視頻
if (isCenter && !AssistPlayer.get().isPlaying()) {
ImageView imageView = view.findViewById(R.id.adapter_video_image);
imageView.performClick();
break;
}
}
}
//滑出屏幕高度一半中止播放
int playPosition = mAdapter.getPlayPosition();
if (playPosition != -1) {
if (isOutSide) {
stopPlay();
}
}
複製代碼
一樣也是RecyclerView實現,這裏滑動播放邏輯跟新聞列表頁有點不一樣(純屬我的理解,理解錯了各位大佬別打我)。進入頁面播放第一個視頻,上滑會加載更多(demo裏面沒有實現)。上下滑動中止後,會播放當前屏幕徹底可見的第一個item的視頻。而且,當播放視頻時,點擊其餘item的任意位置,該item會滑動到頂部並播放視頻。當前視頻播放完畢後,若是列表頁後面還有視頻,會自動播放下一個,並將該item滑到頁面頂部。當退出視頻列表頁時,若是播放的不是第一個視頻,則不須要過渡動畫。 滑動監聽:post
if (newState == SCROLL_STATE_IDLE) {
LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager();
int first = manager.findFirstVisibleItemPosition();
int pos = manager.findFirstCompletelyVisibleItemPosition();
if (pos != mAdapter.getPlayPosition()) {
View view = mRecycler.getChildAt(pos - first);
ImageView imageView = view.findViewById(R.id.adapter_video_list_image);
imageView.performClick();
}
}
複製代碼
由於已經對滑動進行了監聽,因此自動播放下一個視頻能夠經過滑動item來實現:監聽視頻的播放事件,當視頻播放完畢後,判斷該視頻是不是最後一個,不是則滑到屏幕頂部,播放視頻。 PS:滑動要調用smoothScroll方法,不能直接調scroll。動畫
評論頁只是一個播放器容器和一個顯示評論數據的recyclerView(demo裏面沒有作評論蓋樓),這裏不細說,詳見demo。ui
沒辦法羅,只能在當前activity裏面進行過渡了。這裏個人作法是在根佈局添加一個fragment。這裏着重說一下要注意的幾個地方吧:this
下面是頁面過渡的過程:
FragmentTransaction transaction = getFragmentManager().beginTransaction();
Bundle bundle = new Bundle();
bundle.putParcelable("attr", attr);
bundle.putParcelable("news", bean);
commentFragment.setArguments(bundle);
commentFragment.setOnCloseClickListener(this);
transaction.add(R.id.fragment_video_list_comment_container, commentFragment);
transaction.commit();
}
複製代碼
mContainer.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
//繪製完畢,開始執行動畫
mContainer.getViewTreeObserver().removeOnPreDrawListener(this);
mContainer.getLocationOnScreen(location);
mContainer.setTranslationX(mAttr.getX() - location[0]);
mContainer.setTranslationY(mAttr.getY() - location[1]);
mContainer.setScaleX(mAttr.getWidth() / (float) mContainer.getMeasuredWidth());
mContainer.setScaleY(mAttr.getHeight() / (float) mContainer.getMeasuredHeight());
mRecycler.setAlpha(0);
mTextView.setAlpha(0);
mClose.setAlpha(0);
mCommentNum.setAlpha(0);
mContainer.animate().translationX(0).translationY(0).scaleX(1).scaleY(1).setDuration(DURATION);
mRecycler.animate().alpha(1).setDuration(DURATION);
mTextView.animate().alpha(1).setDuration(DURATION);
mClose.animate().alpha(1).setDuration(DURATION);
mCommentNum.animate().alpha(1).setDuration(DURATION);
AssistPlayer.get().play(mContainer, null);
return true;
}
});
複製代碼
附上源碼(Kotlin版可能會有一點語法問題...)
如需更多詳細的效果,可看下一篇博客