前提:
上下滑視頻列表沽甥,實現(xiàn)方式:RecyclerView+LinearLayoutManager
產(chǎn)品需求:
1.黑名單功能。videoList添加author進(jìn)黑名單遂黍,刪除該作者在本地列表的所有視頻终佛。
胖子的思路
image-20210318111750491.png
1.從列表最后往前刪除,防止remove時雾家,由于索引產(chǎn)生變化的bug铃彰。
int tempVideoId = 0;
for (int i = mAdapter.getData().size() - 1; i >= 0; i--) {
BaseVideoBean baseVideoBean = mAdapter.getData().get(i);
if (null == baseVideoBean)
continue;
if (baseVideoBean.getAuthorInfo().getId() == userId) {
if (videoId == baseVideoBean.getId() && i + 1 <= mAdapter.getData().size() - 1) {//當(dāng)刪除到這一項時,判斷是否有下一項芯咧,如果有牙捉,賦值
tempVideoId = mAdapter.getData().get(i + 1).getId();//這里代表刪除項往后推竹揍,第一個未觀看過的視頻
}
mAdapter.removeAt(i);
}
}
2.根據(jù)tempVideoId的值,做相應(yīng)的操作邪铲。
2.1 tempVideoId為0芬位,直接play(size() - 1)
2.2 tempVideoId不為0,找到剩余列表里带到,與之匹配的video昧碉,然后play(對應(yīng)的索引)
然后問題來了
因為視頻上下切換的時候,胖子為了追求性能揽惹,這里是先release播放器被饿,然后再添加。
好了搪搏,在胖子remove完后狭握,立刻去播放相關(guān)視頻,然后毛都沒有疯溺。
最開始的找bug思路:
1.debug论颅,看看index是否正確。
2.debug play()方法囱嫩,看看相關(guān)邏輯恃疯,是否有return。
好了挠说,毫無問題澡谭。
接著,debug RecyclerView.addOnChildAttachStateChangeListener损俭,發(fā)現(xiàn)在胖子移除item時,不是立馬調(diào)用onChildViewDetachedFromWindow潘酗,而是在play之后去調(diào)用杆兵。
mBinding.videoListRecycler.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {
@Override
public void onChildViewAttachedToWindow(@NonNull View view) {
}
@Override
public void onChildViewDetachedFromWindow(@NonNull View view) {
//這里,胖子release播放器
}
});
到這里仔夺,胖子突然想起了琐脏,RecyclerView的notifyItemRemoved是帶動畫效果的,既然帶動畫效果缸兔,那必然就會有duration日裙,去看源碼
private long mAddDuration = 120;
private long mRemoveDuration = 120;
private long mMoveDuration = 250;
private long mChangeDuration = 250;
private void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
final View view = holder.itemView;
final ViewPropertyAnimator animation = view.animate();
mRemoveAnimations.add(holder);
animation.setDuration(getRemoveDuration()).alpha(0).setListener(
new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
dispatchRemoveStarting(holder);
}
@Override
public void onAnimationEnd(Animator animator) {
animation.setListener(null);
view.setAlpha(1);
dispatchRemoveFinished(holder);
mRemoveAnimations.remove(holder);
dispatchFinishedWhenDone();
}
}).start();
}
既然找到了原因,解決方法就油然而生了