Android RecyleView的常见操作内部原理
2019-09-25 本文已影响0人
pj0579
RecyleView
配合使用的高频使用方法有以下几个
1.notifyDataSetChanged
全部更新
‘这个方法经过调用链最后走到AdapterDataObservable
这个被观察者类中的
1.public void notifyChanged() {
for (int i = mObservers.size() - 1; i >= 0; i--) {
// 这里使用了观察者模式 之前进行了一系列的注册
mObservers.get(i).onChanged();
}
}
然后看下onChanged()
2.public void onChanged() {
assertNotInLayoutOrScroll(null);
mState.mStructureChanged = true;
// 这个方法holder.addFlags(ViewHolder.FLAG_UPDATE | ViewHolder.FLAG_INVALID),这个导致RecyleView 的ItemView会重新测量绘制。这种方法会导致一些耗时测量布局的话会出现闪烁情况。通过设置SetHasStableIds(true) 加 getItemId 复写可以解决。
setDataSetChangedAfterLayout();
if (!mAdapterHelper.hasPendingUpdates()) {
// 视图更新
requestLayout();
}
}
2.notifyItemRangeChanged
范围更新
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
assertNotInLayoutOrScroll(null);
if (mAdapterHelper.onItemRangeChanged(positionStart, itemCount, payload)) {
// 这个方法默认也是走的requestLayout(); 这方法有个坑爹的地方时 用在下拉刷新时滑动会抛出异常。一般用在加载更多的时候使用。然后是这种刷新方式搭配动画设置false 也可以实现不测量绘制的功能。
triggerUpdateProcessor();
}
}
3.notifyDataSetChanged
与notifyItemRangeChanged
、 的不同之处在于viewHolder.isInvalid()前者为ture
private void scrapOrRecycleView(Recycler recycler, int index, View view) {
final ViewHolder viewHolder = getChildViewHolderInt(view);
if (viewHolder.shouldIgnore()) {
if (DEBUG) {
Log.d(TAG, "ignoring view " + viewHolder);
}
return;
}
if (viewHolder.isInvalid() && !viewHolder.isRemoved()
&& !mRecyclerView.mAdapter.hasStableIds()) {
removeViewAt(index);
recycler.recycleViewHolderInternal(viewHolder);
} else {
detachViewAt(index);
recycler.scrapView(view);
mRecyclerView.mViewInfoStore.onViewDetached(viewHolder);
}
}
4setItemAnimator
给Item设置动画
public void setItemAnimator(ItemAnimator animator) {
if (mItemAnimator != null) {
mItemAnimator.endAnimations();
mItemAnimator.setListener(null);
}
mItemAnimator = animator;
if (mItemAnimator != null) {
mItemAnimator.setListener(mItemAnimatorListener);
}
}
animator
默认是DefaultItemAnimator
dispatchLayoutStep3
方法里会执行
// Step 4: Process view info lists and trigger animations
1.mViewInfoStore.process(mViewInfoProcessCallback);
mViewInfoProcessCallback 对应
2.private final ViewInfoStore.ProcessCallback mViewInfoProcessCallback =
new ViewInfoStore.ProcessCallback() {
@Override
public void processDisappeared(ViewHolder viewHolder, @NonNull ItemHolderInfo info,
@Nullable ItemHolderInfo postInfo) {
mRecycler.unscrapView(viewHolder);
animateDisappearance(viewHolder, info, postInfo);
}
@Override
public void processAppeared(ViewHolder viewHolder,
ItemHolderInfo preInfo, ItemHolderInfo info) {
animateAppearance(viewHolder, preInfo, info);
}
.......
}
3. void animateAppearance(@NonNull ViewHolder itemHolder,
@Nullable ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo) {
itemHolder.setIsRecyclable(false);
if (mItemAnimator.animateAppearance(itemHolder, preLayoutInfo, postLayoutInfo)) {
postAnimationRunner();
}
}
postAnimationRunner最后调用
4. private Runnable mItemAnimatorRunner = new Runnable() {
@Override
public void run() {
if (mItemAnimator != null) {
mItemAnimator.runPendingAnimations();
}
mPostedAnimatorRunner = false;
}
};
5.runPendingAnimations
此方法根据逻辑执行相关动画