微前端架构如何改变企业的开发模式与效率提升
1351
2022-11-14
Android 探究RecyclerView onViewAttachedToWindow 触发时机
文章目录
RecyclerView 基本使用FruitAdapter
Adapter中的 onAttachedToRecyclerViewAdapter中的 onViewAttachedToWindow
瀑布流 `StaggeredGridLayoutManager` 设置第一个 item 占据一整行
RecyclerView 基本使用
activity_main.xml
item_layout.xml
Fruit
public class Fruit { private String fruitName; public String getFruitName() { return fruitName; } public Fruit(String fruitName) { this.fruitName = fruitName; } //获取数据 public static List
FruitAdapter
public class FruitAdapter extends RecyclerView.Adapter
MainActivity
class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding private var adapter: FruitAdapter? = null private var list = mutableListOf
FruitAdapter
在上面,FruitAdapter 有四个方法
@Override public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) { super.onDetachedFromRecyclerView(recyclerView); } @Override public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); } @Override public void onViewAttachedToWindow(@NonNull ViewHolder holder) { super.onViewAttachedToWindow(holder); } @Override public void onViewDetachedFromWindow(@NonNull ViewHolder holder) { super.onViewDetachedFromWindow(holder); }
Adapter中的 onAttachedToRecyclerView
onAttachedToRecyclerView 、 onDetachedFromRecyclerView 这两个方法是对于 adapter 来说的,当 adapter 和 recyclerView 进行绑定的时候会回调 onAttachedToRecyclerView
什么时候会回调 onDetachedFromRecyclerView ?
答案:recyclerView 已经有 adapter 了,又绑定了一个新的 adapter ,就会执行 onDetachedFromRecyclerView
对于一个 adapter 实例,onAttachedToRecyclerView 、 onDetachedFromRecyclerView 这两个方法只会回调一次。
源码分析:
onAttachedToRecyclerView 、 onDetachedFromRecyclerView 在 RecyclerView 都是空方法。
首先看看 RecyclerView 的 setAdapter 方法
setAdapter 方法里,调用 setAdapterInternal 方法
设置一个新的 adapter , 如果 recyclerView 已经绑定过 adapter 。
那么就对于老的adapter调用 onDetachedFromRecyclerView(this)
新的 adapter 调用 onAttachedToRecyclerView(this)
Adapter中的 onViewAttachedToWindow
@Override public void onViewAttachedToWindow(@NonNull ViewHolder holder) { super.onViewAttachedToWindow(holder); int position = holder.getLayoutPosition(); Log.d("yu--", "attach " + position); } @Override public void onViewDetachedFromWindow(@NonNull ViewHolder holder) { super.onViewDetachedFromWindow(holder); int position = holder.getLayoutPosition(); Log.d("yu--", "detach " + position); }
RecyclerView 本质上也是一个 ViewGroup,那么它的 Item 要显示出来,自然需要 addView() 进来,移出的时候,当然也要 removeView() 出去,所以对应的自然是 onViewAttachedToWindow() 和 onViewAttachedToWindow() 了。
所以在特定场景下,可以通过这两个回调来解决少量 Item 移出屏幕,移进屏幕所需要的工作。为什么说特定场景下呢,由于假如调用了 notifyDataSetChanged() 方法的话,会触发当前在屏幕中的所有 Item 的 onViewAttachedToWindow() 。
当第一次 setAdapter 的时候,屏幕内所有 item 会调用 onViewAttachedToWindow(ViewHolder holder) , 日志如下:
yu--: attach 0yu--: attach 1yu--: attach 2yu--: attach 3yu--: attach 4yu--: attach 5yu--: attach 6
调用 notifyDataSetChanged ,屏幕类所有的 item 会先执行 onViewDetachedFromWindow , 然后执行 onViewAttachedToWindow
yu--: detach 6yu--: detach 5yu--: detach 4yu--: detach 3yu--: detach 2yu--: detach 1yu--: detach 0yu--: attach 0yu--: attach 1yu--: attach 2yu--: attach 3yu--: attach 4yu--: attach 5yu--: attach 6
综上,Adapter 的 onViewAttachedToWindow 适合做 item 曝光埋点,但是要注意,这个方法可能会执行多次。
瀑布流 StaggeredGridLayoutManager 设置第一个 item 占据一整行
@Override public void onViewAttachedToWindow(@NonNull ViewHolder holder) { super.onViewAttachedToWindow(holder); int position = holder.getLayoutPosition(); StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams(); if (position == 0) { //占据一整行 layoutParams.setFullSpan(true); } else { layoutParams.setFullSpan(false); } }
效果图:
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~