學(xué)習(xí)筆記,整理中;
面:
思路:
復(fù)用:從集合中去取
復(fù)用:從集合中去獲取
入口:滑動 Move 事件 --> scrollByInternal --> scrollStep --> mLayout.scrollVerticallyBy
--> scrollBy? --> fill --> layoutChunk? 布局塊--> layoutState.next 布局狀態(tài)--> addView(view);
layoutState.next --> getViewForPosition --> tryGetViewHolderForPositionByDeadline 截止日期 -->
怎么從集合中去獲取:tryGetViewHolderForPositionByDeadline,分幾種情況去獲取ViewHolder
1. getChangedScrapViewForPosition -- mChangeScrap 與動畫相關(guān)
2. getScrapOrHiddenOrCachedHolderForPosition? -- mAttachedScrap附屬廢料 炕淮、mCachedViews 緩存
3. getScrapOrCachedViewForId? -- mAttachedScrap 、mCachedViews (ViewType,itemid)
4. mViewCacheExtension.getViewForPositionAndType -- 自定義緩存 -- (使用情況:局部刷新??)
5. getRecycledViewPool().getRecycledView -- 從緩沖池里面獲取
RecycledViewPool -- 緩存池
ViewHolder -- 包裝View的 --- ItemView
當(dāng)沒有緩存的時候呐矾?悼沈?--- mAdapter.createViewHolder --》 onCreateViewHolder
多級緩存的目的 -- 為了性能
創(chuàng)建ViewHolder 后 綁定: tryBindViewHolderByDeadline--》 mAdapter.bindViewHolder--》onBindViewHolder
回收(緩存)機(jī)制:看這一個情況--- ViewHolder
LinearLayoutManager.onLayoutChildren --> detachAndScrapAttachedViews 分離--> scrapOrRecycleView
--> 1.recycler.recycleViewHolderInternal(viewHolder); -- 處理 CacheView 、RecyclerViewPool 的緩存
--> 1.ViewHodler改變 不會進(jìn)來 -- 先判斷mCachedViews的大小
--> mCachedViews.size 大于默認(rèn)大小? --- recycleCachedViewAt
--- >addViewHolderToRecycledViewPool --- 緩存池里面的數(shù)據(jù)都是從mCachedViews里面出來的
--> 2.addViewHolderToRecycledViewPool --> getRecycledViewPool().putRecycledView(holder);
--> scrap.resetInternal();? ViewHolder 清空
--> 2.recycler.scrapView(view);
mCachedViews當(dāng)前的大小 如果 大于等于mViewCacheMax(默認(rèn)的CachedViews的大小)
ViewType --
緩存池? 里面保存? 只是 ViewHolder 類型 沒有數(shù)據(jù)
去查找緩存和復(fù)用的一種情況
入口:復(fù)用:RecyclerView.onLayout --> dispatchLayout 派遣--》 dispatchLayoutStep2 --》 onLayoutChildren --》 fill
緩存:fill -->recycleByLayoutState-->recycleViewsFromStart --> recycleChildren
--> removeAndRecycleViewAt --> recycler.recycleView
--> recycler.recycleViewHolderInternal(viewHolder); -- 處理 CacheView 塞关、RecyclerViewPool 的緩存
要學(xué)會copy系統(tǒng)的代碼 --- 怎么優(yōu)化
layoutChunk --> layoutDecoratedWithMargins
notifyDataSetChanged-->mObservable.notifyChanged
--> (RecyclerViewDataObserver)mObservers.get(i).onChanged --> requestLayout
mChangeScrap與 mAttachedScrap
用來緩存還在屏幕內(nèi)的 ViewHolder
2.mCachedViews
用來緩存移除屏幕之外的 ViewHolder
3.mViewCacheExtension
開發(fā)給用戶的自定義擴(kuò)展緩存抬探,需要用戶自己管理 View 的創(chuàng)建和緩存
4.RecycledViewPool
ViewHolder 緩存池
—————————-
自定義layoutmanage 繼承recycleview.layout 可以實現(xiàn)布局改變 在界面上拖動或者拖拽,settranslationy拖動 setscrolx縮放
SlideCallback extends ItemTouchHelper.SimpleCallback
SlideCardLayoutManagerextends RecyclerView.LayoutManager
------------------------------------------------------------------------
public class MainActivityextends AppCompatActivity {
private RecyclerViewrv;
? ? private UniversalAdapteradapter;
? ? private ListmDatas;
? ? @Override
? ? protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
? ? ? ? setContentView(R.layout.activity_main);
? ? ? ? rv = findViewById(R.id.rv);
? ? ? ? rv.setLayoutManager(new SlideCardLayoutManager());
? ? ? ? mDatas = SlideCardBean.initDatas();
? ? ? ? adapter =new UniversalAdapter(this, mDatas, R.layout.item_swipe_card) {
@Override
? ? ? ? ? ? public void convert(ViewHolder viewHolder, SlideCardBean slideCardBean) {
viewHolder.setText(R.id.tvName, slideCardBean.getName());
? ? ? ? ? ? ? ? viewHolder.setText(R.id.tvPrecent, slideCardBean.getPostition() +"/" +mDatas.size());
? ? ? ? ? ? ? ? Glide.with(MainActivity.this)
.load(slideCardBean.getUrl())
.into((ImageView) viewHolder.getView(R.id.iv));
? ? ? ? ? ? }
};
? ? ? ? rv.setAdapter(adapter);
? ? ? ? // 初始化數(shù)據(jù)
? ? ? ? CardConfig.initConfig(this);
? ? ? ? SlideCallback slideCallback =new SlideCallback(rv, adapter, mDatas);
? ? ? ? ItemTouchHelper itemTouchHelper =new ItemTouchHelper(slideCallback);
? ? ? ? itemTouchHelper.attachToRecyclerView(rv);
? ? }
}
------------------------------------------------------------------------
public class SlideCardLayoutManagerextends RecyclerView.LayoutManager {
@Override
? ? public RecyclerView.LayoutParamsgenerateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
? ? ? ? ? ? ? ? ViewGroup.LayoutParams.WRAP_CONTENT);
? ? }
// 布局
? ? @Override
? ? public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
// ViewHodler回收復(fù)用
? ? ? ? detachAndScrapAttachedViews(recycler);
? ? ? ? int bottomPosition;
? ? ? ? int itemCount = getItemCount();
? ? ? ? if (itemCount < CardConfig.MAX_SHOW_COUNT) {
bottomPosition =0;
? ? ? ? }else {
// 布局了四張卡片 --- 4帆赢,5小压,6,7
? ? ? ? ? ? bottomPosition = itemCount - CardConfig.MAX_SHOW_COUNT;
? ? ? ? }
for (int i = bottomPosition; i < itemCount; i++) {
// 復(fù)用
? ? ? ? ? ? View view = recycler.getViewForPosition(i);
? ? ? ? ? ? addView(view);
? ? ? ? ? ? measureChildWithMargins(view, 0, 0);
? ? ? ? ? ? int widthSpace = getWidth() - getDecoratedMeasuredWidth(view);
? ? ? ? ? ? int heightSpace = getHeight() - getDecoratedMeasuredHeight(view);
? ? ? ? ? ? // 布局 ---draw -- onDraw ,onDrawOver, onLayout
? ? ? ? ? ? layoutDecoratedWithMargins(view, widthSpace /2, heightSpace /2,
? ? ? ? ? ? ? ? ? ? widthSpace /2 + getDecoratedMeasuredWidth(view),
? ? ? ? ? ? ? ? ? ? heightSpace /2 + getDecoratedMeasuredHeight(view));
? ? ? ? ? ? int level = itemCount - i -1;
? ? ? ? ? ? if (level >0) {
if (level < CardConfig.MAX_SHOW_COUNT -1) {
view.setTranslationY(CardConfig.TRANS_Y_GAP * level);
? ? ? ? ? ? ? ? ? ? view.setScaleX(1 - CardConfig.SCALE_GAP * level);
? ? ? ? ? ? ? ? ? ? view.setScaleY(1 - CardConfig.SCALE_GAP * level);
? ? ? ? ? ? ? ? }else {
// 最下面的那個view 與前一個view 布局一樣
? ? ? ? ? ? ? ? ? ? view.setTranslationY(CardConfig.TRANS_Y_GAP * (level -1));
? ? ? ? ? ? ? ? ? ? view.setScaleX(1 - CardConfig.SCALE_GAP * (level -1));
? ? ? ? ? ? ? ? ? ? view.setScaleY(1 - CardConfig.SCALE_GAP * (level -1));
? ? ? ? ? ? ? ? }
}
}
}
}
------------------------------------------------------------------------
public class SlideCallbackextends ItemTouchHelper.SimpleCallback {
private RecyclerViewmRv;
? ? private UniversalAdapteradapter;
? ? private ListmDatas;
? ? public SlideCallback(RecyclerView mRv,
? ? ? ? ? ? ? ? ? ? ? ? UniversalAdapter adapter, List mDatas) {
super(0, 15);
? ? ? ? this.mRv = mRv;
? ? ? ? this.adapter = adapter;
? ? ? ? this.mDatas = mDatas;
? ? }
// drag? 拖拽
? ? @Override
? ? public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return false;
? ? }
// 滑動
? ? @Override
? ? public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
SlideCardBean remove =mDatas.remove(viewHolder.getLayoutPosition());
? ? ? ? mDatas.add(0, remove);
? ? ? ? adapter.notifyDataSetChanged();// onMeasure, onlayout
? ? }
// onDra
? ? @Override
? ? public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
? ? ? ? double maxDistance = recyclerView.getWidth() *0.5f;
? ? ? ? double distance = Math.sqrt(dX * dX + dY * dY);
? ? ? ? double fraction = distance / maxDistance;
? ? ? ? if (fraction >1) {
fraction =1;
? ? ? ? }
// 顯示的個數(shù)? 4個
? ? ? ? int itemCount = recyclerView.getChildCount();
? ? ? ? for (int i =0; i < itemCount; i++) {
View view = recyclerView.getChildAt(i);
? ? ? ? ? ? int level = itemCount - i -1;
? ? ? ? ? ? if (level >0) {
if (level < CardConfig.MAX_SHOW_COUNT -1) {
view.setTranslationY((float) (CardConfig.TRANS_Y_GAP * level - fraction * CardConfig.TRANS_Y_GAP));
? ? ? ? ? ? ? ? ? ? view.setScaleX((float) (1 - CardConfig.SCALE_GAP * level + fraction * CardConfig.SCALE_GAP));
? ? ? ? ? ? ? ? ? ? view.setScaleY((float) (1 - CardConfig.SCALE_GAP * level + fraction * CardConfig.SCALE_GAP));
? ? ? ? ? ? ? ? }
}
}
}
@Override
? ? public long getAnimationDuration(@NonNull RecyclerView recyclerView, int animationType, float animateDx, float animateDy) {
return 1500;
? ? }
}
------------------------------------------------------------------------
------------------------------------------------------------------------