-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2c6fd7f
commit 6dc60bb
Showing
34 changed files
with
8,422 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
#### 目录介绍 | ||
- 01.RecyclerView的结构 | ||
- 02.RecyclerView简单用法 | ||
- 03.RecyclerView思路 | ||
|
||
|
||
### 好消息 | ||
- 博客笔记大汇总【16年3月到至今】,包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期更新维护并且修正,持续完善……开源的文件是markdown格式的!同时也开源了生活博客,从12年起,积累共计N篇[近100万字,陆续搬到网上],转载请注明出处,谢谢! | ||
- **链接地址:https://github.com/yangchong211/YCBlogs** | ||
- 如果觉得好,可以star一下,谢谢!当然也欢迎提出建议,万事起于忽微,量变引起质变! | ||
|
||
|
||
|
||
|
||
### 01.RecycleView的结构 | ||
- 关于RecyclerView,大家都已经很熟悉了,用途十分广泛,大概结构如下所示 | ||
* RecyclerView.Adapter - 处理数据集合并负责绑定视图 | ||
* ViewHolder - 持有所有的用于绑定数据或者需要操作的View | ||
* LayoutManager - 负责摆放视图等相关操作 | ||
* ItemDecoration - 负责绘制Item附近的分割线 | ||
* ItemAnimator - 为Item的一般操作添加动画效果,如,增删条目等 | ||
- 如图所示,直观展示结构 | ||
- ![image](https://upload-images.jianshu.io/upload_images/4432347-6301e0c8563ecda0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) | ||
|
||
|
||
|
||
### 02.RecyclerView简单用法[博客](https://github.com/yangchong211/YCBlogs) | ||
- 针对上面几个属性,最简单用法如下所示 | ||
``` | ||
recyclerView = (RecyclerView) findViewById(R.id.recyclerView); | ||
LinearLayoutManager layoutManager = new LinearLayoutManager(this); | ||
//设置layoutManager | ||
recyclerView.setLayoutManager(layoutManager); | ||
final RecycleViewItemLine line = new RecycleViewItemLine(this, LinearLayout.HORIZONTAL,1,this.getResources().getColor(R.color.colorAccent)); | ||
//设置添加分割线 | ||
recyclerView.addItemDecoration(line); | ||
adapter = new MultipleItemAdapter(this); | ||
//设置adapter | ||
recyclerView.setAdapter(adapter); | ||
//添加数据并且刷新adapter | ||
adapter.addAll(list); | ||
adapter.notifyDataSetChanged(); | ||
//adapter | ||
//onCreateViewHolder(ViewGroup parent, int viewType)这里的第二个参数就是View的类型,可以根据这个类型判断去创建不同item的ViewHolder | ||
public class MultipleItemAdapter extends RecyclerView.Adapter<recyclerview.viewholder> { | ||
public static enum ITEM_TYPE { | ||
ITEM_TYPE_IMAGE, | ||
ITEM_TYPE_TEXT | ||
} | ||
private final LayoutInflater mLayoutInflater; | ||
private final Context mContext; | ||
private ArrayList<String> mTitles; | ||
public MultipleItemAdapter(Context context) { | ||
mContext = context; | ||
mLayoutInflater = LayoutInflater.from(context); | ||
} | ||
@Override | ||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { | ||
if (viewType == ITEM_TYPE.ITEM_TYPE_IMAGE.ordinal()) { | ||
return new ImageViewHolder(mLayoutInflater.inflate(R.layout.item_image, parent, false)); | ||
} else { | ||
return new TextViewHolder(mLayoutInflater.inflate(R.layout.item_text, parent, false)); | ||
} | ||
} | ||
@Override | ||
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { | ||
if (holder instanceof TextViewHolder) { | ||
((TextViewHolder) holder).mTextView.setText(mTitles[position]); | ||
} else if (holder instanceof ImageViewHolder) { | ||
((ImageViewHolder) holder).mTextView.setText(mTitles[position]); | ||
} | ||
} | ||
@Override | ||
public int getItemViewType(int position) { | ||
return position % 2 == 0 ? ITEM_TYPE.ITEM_TYPE_IMAGE.ordinal() : ITEM_TYPE.ITEM_TYPE_TEXT.ordinal(); | ||
} | ||
@Override | ||
public int getItemCount() { | ||
return mTitles == null ? 0 : mTitles.length; | ||
} | ||
public void addAll(ArrayList<String> list){ | ||
if(mTitles!=null){ | ||
mTitles.clear(); | ||
}else { | ||
mTitles = new ArrayList<>(); | ||
} | ||
mTitles.addAll(list); | ||
} | ||
public static class TextViewHolder extends RecyclerView.ViewHolder { | ||
@InjectView(R.id.text_view) | ||
TextView mTextView; | ||
TextViewHolder(View view) { | ||
super(view); | ||
ButterKnife.inject(this, view); | ||
} | ||
} | ||
public static class ImageViewHolder extends RecyclerView.ViewHolder { | ||
@InjectView(R.id.text_view) | ||
TextView mTextView; | ||
@InjectView(R.id.image_view) | ||
ImageView mImageView; | ||
ImageViewHolder(View view) { | ||
super(view); | ||
ButterKnife.inject(this, view); | ||
} | ||
} | ||
} | ||
``` | ||
### 其他介绍 | ||
#### 01.关于博客汇总链接 | ||
- 1.[技术博客汇总](https://www.jianshu.com/p/614cb839182c) | ||
- 2.[开源项目汇总](https://blog.csdn.net/m0_37700275/article/details/80863574) | ||
- 3.[生活博客汇总](https://blog.csdn.net/m0_37700275/article/details/79832978) | ||
- 4.[喜马拉雅音频汇总](https://www.jianshu.com/p/f665de16d1eb) | ||
- 5.[其他汇总](https://www.jianshu.com/p/53017c3fc75d) | ||
#### 02.关于我的博客 | ||
- github:https://github.com/yangchong211 | ||
- 知乎:https://www.zhihu.com/people/yczbj/activities | ||
- 简书:http://www.jianshu.com/u/b7b2c6ed9284 | ||
- csdn:http://my.csdn.net/m0_37700275 | ||
- 喜马拉雅听书:http://www.ximalaya.com/zhubo/71989305/ | ||
- 开源中国:https://my.oschina.net/zbj1618/blog | ||
- 泡在网上的日子:http://www.jcodecraeer.com/member/content_list.php?channelid=1 | ||
- 邮箱:[email protected] | ||
- 阿里云博客:https://yq.aliyun.com/users/article?spm=5176.100- 239.headeruserinfo.3.dT4bcV | ||
- segmentfault头条:https://segmentfault.com/u/xiangjianyu/articles | ||
- 掘金:https://juejin.im/user/5939433efe88c2006afa0c6e | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
#### 目录介绍 | ||
- 01.RecyclerView.Adapter扮演的角色 | ||
- 02.重写的方法 | ||
- 03.notifyDataSetChanged()刷新数据 | ||
- 04.数据变更通知之观察者模式 | ||
* a.首先看.notifyDataSetChanged()源码 | ||
* b.接着查看.notifyChanged()源码 | ||
* c.接着查看setAdapter()源码中的setAdapterInternal(adapter, false, true)方法 | ||
* d.notify……方法被调用,刷新数据 | ||
- 05.onViewDetachedFromWindow | ||
|
||
|
||
### 好消息 | ||
- 博客笔记大汇总【16年3月到至今】,包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期更新维护并且修正,持续完善……开源的文件是markdown格式的!同时也开源了生活博客,从12年起,积累共计N篇[近100万字,陆续搬到网上],转载请注明出处,谢谢! | ||
- **链接地址:https://github.com/yangchong211/YCBlogs** | ||
- 如果觉得好,可以star一下,谢谢!当然也欢迎提出建议,万事起于忽微,量变引起质变! | ||
|
||
|
||
|
||
|
||
### 01.RecyclerView.Adapter扮演的角色 | ||
- 一是,根据不同ViewType创建与之相应的的Item-Layout | ||
- 二是,访问数据集合并将数据绑定到正确的View上 | ||
|
||
|
||
|
||
|
||
### 02.重写的方法 | ||
- 一般常用的重写方法有以下这么几个: | ||
``` | ||
public VH onCreateViewHolder(ViewGroup parent, int viewType) | ||
创建Item视图,并返回相应的ViewHolder | ||
public void onBindViewHolder(VH holder, int position) | ||
绑定数据到正确的Item视图上。 | ||
public int getItemCount() | ||
返回该Adapter所持有的Itme数量 | ||
public int getItemViewType(int position) | ||
用来获取当前项Item(position参数)是哪种类型的布局 | ||
``` | ||
### 03.notifyDataSetChanged()刷新数据 | ||
- 当时据集合发生改变时,我们通过调用.notifyDataSetChanged(),来刷新列表,因为这样做会触发列表的重绘,所以并不会出现任何动画效果,因此需要调用一些以notifyItem*()作为前缀的特殊方法,比如:[博客](https://github.com/yangchong211/YCBlogs) | ||
* public final void notifyItemInserted(int position) 向指定位置插入Item | ||
* public final void notifyItemRemoved(int position) 移除指定位置Item | ||
* public final void notifyItemChanged(int position) 更新指定位置Item | ||
### 04.数据变更通知之观察者模式 | ||
- a.首先看.notifyDataSetChanged()源码 | ||
``` | ||
/** @see #notifyItemChanged(int) | ||
* @see #notifyItemInserted(int) | ||
* @see #notifyItemRemoved(int) | ||
* @see #notifyItemRangeChanged(int, int) | ||
* @see #notifyItemRangeInserted(int, int) | ||
* @see #notifyItemRangeRemoved(int, int) | ||
*/ | ||
public final void notifyDataSetChanged() { | ||
mObservable.notifyChanged(); | ||
} | ||
``` | ||
- b.接着查看.notifyChanged();源码 | ||
* 被观察者AdapterDataObservable,内部持有观察者AdapterDataObserver集合 | ||
``` | ||
static class AdapterDataObservable extends Observable<AdapterDataObserver> { | ||
public boolean hasObservers() { | ||
return !mObservers.isEmpty(); | ||
} | ||
public void notifyChanged() { | ||
for (int i = mObservers.size() - 1; i >= 0; i--) { | ||
mObservers.get(i).onChanged(); | ||
} | ||
} | ||
public void notifyItemRangeChanged(int positionStart, int itemCount) { | ||
notifyItemRangeChanged(positionStart, itemCount, null); | ||
} | ||
public void notifyItemRangeChanged(int positionStart, int itemCount, Object payload) { | ||
for (int i = mObservers.size() - 1; i >= 0; i--) { | ||
mObservers.get(i).onItemRangeChanged(positionStart, itemCount, payload); | ||
} | ||
} | ||
public void notifyItemRangeInserted(int positionStart, int itemCount) { | ||
for (int i = mObservers.size() - 1; i >= 0; i--) { | ||
mObservers.get(i).onItemRangeInserted(positionStart, itemCount); | ||
} | ||
} | ||
} | ||
``` | ||
* 观察者AdapterDataObserver,具体实现为RecyclerViewDataObserver,当数据源发生变更时,及时响应界面变化 | ||
``` | ||
public static abstract class AdapterDataObserver { | ||
public void onChanged() { | ||
// Do nothing | ||
} | ||
public void onItemRangeChanged(int positionStart, int itemCount) { | ||
// do nothing | ||
} | ||
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) { | ||
onItemRangeChanged(positionStart, itemCount); | ||
} | ||
} | ||
``` | ||
- c.接着查看setAdapter()源码中的setAdapterInternal(adapter, false, true)方法 | ||
* setAdapter源码[博客](https://github.com/yangchong211/YCBlogs) | ||
``` | ||
public void setAdapter(Adapter adapter) { | ||
// bail out if layout is frozen | ||
setLayoutFrozen(false); | ||
setAdapterInternal(adapter, false, true); | ||
requestLayout(); | ||
} | ||
``` | ||
* setAdapterInternal(adapter, false, true)源码 | ||
``` | ||
private void setAdapterInternal(Adapter adapter, boolean compatibleWithPrevious, | ||
boolean removeAndRecycleViews) { | ||
if (mAdapter != null) { | ||
mAdapter.unregisterAdapterDataObserver(mObserver); | ||
mAdapter.onDetachedFromRecyclerView(this); | ||
} | ||
if (!compatibleWithPrevious || removeAndRecycleViews) { | ||
removeAndRecycleViews(); | ||
} | ||
mAdapterHelper.reset(); | ||
final Adapter oldAdapter = mAdapter; | ||
mAdapter = adapter; | ||
if (adapter != null) { | ||
//注册一个观察者RecyclerViewDataObserver | ||
adapter.registerAdapterDataObserver(mObserver); | ||
adapter.onAttachedToRecyclerView(this); | ||
} | ||
if (mLayout != null) { | ||
mLayout.onAdapterChanged(oldAdapter, mAdapter); | ||
} | ||
mRecycler.onAdapterChanged(oldAdapter, mAdapter, compatibleWithPrevious); | ||
mState.mStructureChanged = true; | ||
markKnownViewsInvalid(); | ||
} | ||
``` | ||
- d.notify……方法被调用,刷新数据 | ||
* 当数据变更时,调用notify**方法时,Adapter内部的被观察者会遍历通知已经注册的观察者的对应方法,这时界面就会响应变更。[博客](https://github.com/yangchong211/YCBlogs) | ||
### 05.onViewDetachedFromWindow | ||
- 先来看一下源码 | ||
``` | ||
/** | ||
* Called when a view created by this adapter has been detached from its window. | ||
* | ||
* <p>Becoming detached from the window is not necessarily a permanent condition; | ||
* the consumer of an Adapter's views may choose to cache views offscreen while they | ||
* are not visible, attaching an detaching them as appropriate.</p> | ||
* | ||
* @param holder Holder of the view being detached | ||
*/ | ||
public void onViewDetachedFromWindow(VH holder) { | ||
} | ||
``` | ||
- 该方法何时调用 | ||
- 当适配器创建的view(即列表项view)被窗口分离(即滑动离开了当前窗口界面)就会被调用 | ||
- 有何作用 | ||
- 这个方法就是用来当你的列表项滑出可见窗口之外的时候,需要重写此方法进行相应的一些操作。 | ||
- 这个方法具体什么时候用呢?比如:我有一个列表,列表的每一个列表项里面都要播放一个短视频,这时候,当我滑动一个列表项直至它消失在可视界面时,便会调用onViewDetachedFromWindow()方法,重要的一点,视频控件也会执行它自己的onViewDetachedFromWindow()方法,那么此时我再滑动回来,让该列表项出现在当前界面,会发现视频那一部分就是黑屏或者白屏了。注意,出现这个Bug的条件是,该列表项滑动出可视界面,但是滑动距离不长,因为长的话,你再滑回来就会复用View执行onBindViewHolder()方法。解决方法就是在RecyclerView中重写onViewDetachedFromWindow()方法,对视频进行一个相应的操作(初始化等等)。 | ||
### 其他介绍 | ||
#### 01.关于博客汇总链接 | ||
- 1.[技术博客汇总](https://www.jianshu.com/p/614cb839182c) | ||
- 2.[开源项目汇总](https://blog.csdn.net/m0_37700275/article/details/80863574) | ||
- 3.[生活博客汇总](https://blog.csdn.net/m0_37700275/article/details/79832978) | ||
- 4.[喜马拉雅音频汇总](https://www.jianshu.com/p/f665de16d1eb) | ||
- 5.[其他汇总](https://www.jianshu.com/p/53017c3fc75d) | ||
#### 02.关于我的博客 | ||
- github:https://github.com/yangchong211 | ||
- 知乎:https://www.zhihu.com/people/yczbj/activities | ||
- 简书:http://www.jianshu.com/u/b7b2c6ed9284 | ||
- csdn:http://my.csdn.net/m0_37700275 | ||
- 喜马拉雅听书:http://www.ximalaya.com/zhubo/71989305/ | ||
- 开源中国:https://my.oschina.net/zbj1618/blog | ||
- 泡在网上的日子:http://www.jcodecraeer.com/member/content_list.php?channelid=1 | ||
- 邮箱:[email protected] | ||
- 阿里云博客:https://yq.aliyun.com/users/article?spm=5176.100- 239.headeruserinfo.3.dT4bcV | ||
- segmentfault头条:https://segmentfault.com/u/xiangjianyu/articles | ||
- 掘金:https://juejin.im/user/5939433efe88c2006afa0c6e | ||
Oops, something went wrong.