notifyDataSetChanged为什么会增加recyclerview 行间距间距?

RecyclerView遇到notifyDataSetChanged无效时的解决方案 - 简书
RecyclerView遇到notifyDataSetChanged无效时的解决方案
创微信公众号郭霖 WeChat ID: guolin_blog本篇来自CSDN_LQR的投稿,分析了Fragment中使用RecyclerView时notifyDataSetChanged可能出现的问题,希望能够帮助到大家。CSDN_LQR的博客地址:/u/f9de简述不管 AbsListView(ListView、GridView) 或是 新出的RecyclerView,在使用 notifyDataSetChanged方法 更新列表数据时,一定要保证数据为同个对象(即hashCode要一致)。对于这个问题的论证,可以去看官方源代码,或是看我之前写的一篇博文解决ListViews适配器notifyDataSetChanged()无效问题http://blog.csdn.net/csdn_lqr/article/details/相信可以帮到你。但是,这个不是本文的重点,本文重点讲解在 Fragment 中,RecyclerView 遇到 notifyDataSetChanged 无效的问题。如果你赶时间,可以直接看第三部分("总结")。探索1、查看数据(mData)是否是同个对象tip:java中可以通过打印 hashCode 的方式判断 mData 是否为同个对象。注意:initData方法 在 onActivityCreated() 中被调用。
2、操作与结果tip:常规对 Fragment 的使用,会对其进行缓存,也可能使用单例模式,反正就是短时间内不会重新创建。①操作一打开 Activity 后,切换 Fragment(第一次初始化 Fragment)。显示效果如下:
②操作二切换别的 Fragment 后,再切回刚才的 Fragment(此前该 Fragment 已经在存在,所以不会再次创建)。显示效果如下:
③看控制台
可以看到数据对象地址一样,即为同一个。3、查看RecyclerView是否是同个对象说实话,这个是踩坑经验丰富的网友在群里说的,如果不是他说出来,打死我也没想到,居然还有这么一个坑。从上面的结果可以看出,adapter 中是有数据的没错,而且数据地址没变,所以理应 notifyDataSetChanged()方法 会生效。但是为什么会这样呢,这里先卖个关子,先看下面的操作。①改下上面的代码,打印RecyclerView的地址代码如下:
②同上述操作一致对同一个 Fragment 来回切换,看控制台输出。
果然不一样!!!总结为什么在 Fragment 中 RecyclerView 的地址会发生变化呢?我们先理清一下 Fragment 生命周期会陆续调用的几个方法:onCreate()-&onCreateView()-&onActivityCreated()-&onDestroy()中间少了几个方法,请不用在意,下面贴下我的 BaseFragment 代码:
当一个 Fragment 在来回切换时,分别调用的方法如下:第一次显示:onCreate()-&onCreateView()-&onActivityCreated()第二次显示:onCreateView()-&onActivityCreated()这里不难理解,因为 Fragment 一般使用的时候会被缓存,所以,当第二次显示的时候,不会调用 onCreate()。只会调用 onCreateView() 和 onActivityCreated(),这也就是 RecyclerView 地址不一样的原因所在,因为控件获取操作是在 initView() 中进行的,即 RecyclerView 的获取操作在 onCreateView() 中,而 Fragment 的每次显示都会调用 onCreateView(),所以 RecyclerView 控件会被再次获取,即重新创建一个对象(此时hashCode就变化了)。结论所以,在 Fragment 中使用 RecyclerView 或 AbsListView 控件的 notifyDataSetChanged()方法 时,除了保证数据(mData对象)不能变以外,控件本身一样也不能变。解决方案因为 Fragment 的 onCreateView() 和 onActivityCreated() 方法在每次 Fragment 显示的时候会被调用,控件会被重新创建一次,所以,解决方法只能是在这两个方法中重新对RecyclerView 设置适配器,而不要使用 notifyDataSetChanged(),故代码改为如下:
注:只是建议不要在上述两个生命周期方法中使用 notifyDataSetChanged() 而已,只要在保证 RecyclerView 等列表控件设置完适配器后,可以在任意地方继续使用 notifyDataSetChanged()。文章原创作者GuoLin 书籍推荐郭林大神原创android 书籍:《第一行代码 android》2012年4月 专题开发/技术/项目大版内专家分月排行榜第二2012年3月 专题开发/技术/项目大版内专家分月排行榜第二
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。17:21 提问
RecyclerView的notifyDataSetChanged无效
mLikeUsersRecyclerViewAdapter.updateData(mARTICLEs.get(pos).like_users);
我是先把更新完的数据作为参数传给updateData方法
在updateData方法中
this.like_users = like_
notifyDataSetChanged();
将数据赋给适配器中的容器,最后调用notifyDataSetChanged。
但是RecyclerView没有更新
我断点调试发现程序最后调用notifyDataSetChanged后
没有调用适配器的onBindViewHolder。
求教啊。。。
PS:我的RecyclerView是放在一个ListView的Item里面,方向为横向的
在线等。。。急
按赞数排序
@bigname22 问题解决了,刚才灵基异动,想到了一个可能性,我这个RecyclerView是作为一个ListView的Item中的一部分的,之前数据改变时
我只是调用了RecyclerView的notifyDataser,但是没有更新外层ListView的,我试着调用了一下外层Listview的notifyDataSetChanged,然后就OK了。
mLikeUsersRecyclerViewAdapter.updateData(mARTICLEs.get(pos).like_users);
notifyDataSetChanged();
总之,谢谢各位了。
首先你要确定你的数据确确实实已经更改了。因为view的刷新是和里面的数据息息相关的。参与view绘制的数据更改之后,notify才会更新view。所以你要先
检测数据是否更改
试试ListView也notifyDataSetChanged
刚才打断点发现可以进onBindViewHolder方法了。。。但是RecyclerView任然没有刷新
因为没看到你的源码,so...
有可能是这个问题:this.like_users = like_,不能直接这么赋值的呢,
如果他是一个集合的话,试下下面这个方法:
this.like_users.clear();
this.like_user.addAll(list_user);
希望对你有用。
(如果成功的话,还有什么疑问的话再@我)
按照你的方法做了,RecyclerView还是没有更新......
public class LikeUsersRecyclerViewAdapter extends RecyclerView.Adapter {
private LayoutInflater mI
private Context mC
private List&User2& like_users = new ArrayList&&();
private OnItemClickListener mOnItemClickL
private int article_
public LikeUsersRecyclerViewAdapter(Context context, List&User2& users, int article_pos) {
mContext =
like_users.clear();
like_users.addAll(users);
like_users =
mInflater = LayoutInflater.from(mContext);
width = ViewUtils.getDefaultDisplay(true,mContext);// 获取屏幕宽度
height = ViewUtils.getDefaultDisplay(false, mContext);//获取屏幕高度
this.article_pos = article_
//更新RecyclerView的数据
public void updateData(List&User2& users) {
this.like_users.clear();
this.like_users.addAll(users);
notifyDataSetChanged();
* 自定义一个Item点击借口
public interface OnItemClickListener{
void OnItemClick(View view, int position, int article_pos);
public LikeUsersViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LikeUsersViewHolder holder = new LikeUsersViewHolder(mInflater.inflate(R.layout.item_like_users_recyclerview, parent, false));
public int getItemCount() {
return like_users.size();
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
mOnItemClickListener = onItemClickL
public void onBindViewHolder(final LikeUsersViewHolder holder, int position) {
if (like_users.get(position).avatar_img==null || like_users.get(position).avatar_img.isEmpty()){
holder.like_user.setImageResource(R.drawable.image_default_picture);
Utils.getImage(mContext, holder.like_user, like_users.get(position).avatar_img);
ViewUtils.setLayoutParams(holder.like_user, 0, 5, 0, 5, width/10, width/10);
if (mOnItemClickListener != null){
holder.itemView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int pos = holder.getLayoutPosition();
mOnItemClickListener.OnItemClick(null ,pos, article_pos);
class LikeUsersViewHolder extends RecyclerView.ViewHolder{
CircleImageView like_
public LikeUsersViewHolder(View itemView) {
super(itemView);
like_user = (CircleImageView) itemView.findViewById(R.id.id_like_user);
这是RecyclerView的适配器
@bigname22
其他相关推荐[android]RecyclerView notifyDataSetChanged 解析查询后不工作
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.
我在 fragment 试图更新我回收 view 后对某些数据的查询分析。在 done 方法查询我叫 notifyDataSetChagned ,但永远不会显示列表
包 com.garciaericn.t2d.fragments ;
public class DevicesCardViewFragment extends Fragment implements View.OnClickListener {
private OnFragmentInteractionListener mL
private BatteryHelper mBatteryH
Intent mBatteryS
private RecyclerView mRecyclerV
private DeviceAdapter mA
private RecyclerView.LayoutManager mLayoutM
private List&Device& mD
public DevicesCardViewFragment() {
// Required empty public constructor
mDevices = new ArrayList&Device&();
public static DevicesCardViewFragment newInstance() {
// Bundle parameters is necessary
return new DevicesCardViewFragment();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get arguments
getDevices();
mBatteryHelper = new BatteryHelper(getActivity());
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
mBatteryStatus = getActivity().registerReceiver(null, intentFilter);
// Update stats of current device.
Toast.makeText(getActivity(), "Battery level: " + mBatteryHelper.getCurrentBatteryLevel() + "%", Toast.LENGTH_LONG).show();
// Update device stats
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_devices_list, container, false);
mListener.showAd();
// Obtain recycler view
mRecyclerView = (RecyclerView) view.findViewById(R.id.devices_recycler_view);
mRecyclerView.setHasFixedSize(true);
mAdapter = new DeviceAdapter(getActivity(), mDevices);
// Set adapter
mRecyclerView.setAdapter(mAdapter);
// Set layout manager
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
public void onAttach(Activity activity) {
super.onAttach(activity);
mListener = (OnFragmentInteractionListener)
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
public void onDetach() {
super.onDetach();
mListener =
public List&Device& getDevices() {
ParseQuery&Device& query = ParseQuery.getQuery(Device.DEVICES);
new ParseQuery&Device&(Device.DEVICES);
query.whereEqualTo("deviceUser", ParseUser.getCurrentUser());
query.findInBackground(new FindCallback&Device&() {
public void done(List&Device& devices, ParseException e) {
if (e == null) {
// Loop through return devices
for (Device device : devices) {
Device currentDevice = new Device();
currentDevice.setDeviceName(device.getDeviceName());
currentDevice.setBatteryLevel(device.getBatteryLevel());
currentDevice.setIsCharging(device.isCharging());
mDevices.add(currentDevice);
mAdapter.notifyDataSetChanged();
// Something went wrong
Toast.makeText(getActivity(), "Error: " + e.toString(), Toast.LENGTH_LONG).show();
public void onClick(View v) {
// Click events go here
public static DevicesCardViewFragment newInstance(List&Device& mDevices) {
DevicesCardViewFragment fragment = new DevicesCardViewFragment();
Bundle args = new Bundle();
public interface OnFragmentInteractionListener {
public void showAd();
我的 recyclerViewAdapter 看起来像这样......
package com.garciaericn.t2d.
public class DeviceAdapter extends RecyclerView.Adapter&DeviceAdapter.MyViewHolder& {
private final LayoutI
List&Device& data = Collections.emptyList();
public DeviceAdapter(Context context, List&Device& data) {
inflater = LayoutInflater.from(context);
this.data =
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.card_layout, parent, false);
MyViewHolder holder = new MyViewHolder(view);
public void onBindViewHolder(MyViewHolder holder, int position) {
Device device = data.get(position);
holder.deviceNameTV.setText(device.getDeviceName());
holder.batteryLevelTV.setText(device.getBatteryLevel());
public int getItemCount() {
public static class MyViewHolder extends RecyclerView.ViewHolder {
// Temp data set
private String[] mD
TextView deviceNameTV;
TextView batteryLevelTV;
public MyViewHolder(View itemView) {
super(itemView);
deviceNameTV = (TextView) itemView.findViewById(R.id.device_name_tv);
batteryLevelTV = (TextView) itemView.findViewById(R.id.battery_level_tv);
解决方法 1:
变化 getItemCount() ,实际上返回正确的值:
public int getItemCount() {
return data.size()问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
我给RecyclerView添加了一个头部,如果使用notifyDataSetChanged会照成头部的刷新,所以我想局部删除一些数据,但是调用notifyItemRangeRemoved方法无效,
if (videoSetting.getVideoPictures() != null && videoSetting.getVideoPictures().size() & 0) {
cameraPhotoList.clear();
cameraPhotoList.addAll(videoSetting.getVideoPictures());
mAdapter.notifyItemRangeChanged(1,cameraPhotoList.size());
int count = cameraPhotoList.size();
cameraPhotoList.clear();
mAdapter.notifyItemRangeRemoved(1,count);
mAdapter.notifyItemRangeRemoved(1,count);
在获取到数据的时候更新数据,数据为空的话清空数据,不知道为什么,我调用两次notifyItemRangeRemoved成功实现了
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
RecyclerView相对于ListView的改进之一就是支持局部刷新,包含插入,删除或更新或许是调用的方法有问题,贴代码出来看看
分享到微博?
你好!看起来你挺喜欢这个内容,但是你还没有注册帐号。 当你创建了帐号,我们能准确地追踪你关注的问题,在有新答案或内容的时候收到网页和邮件通知。还能直接向作者咨询更多细节。如果上面的内容有帮助,记得点赞 (????)? 表示感谢。
明天提醒我
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:

我要回帖

更多关于 recyclerview 列间距 的文章

 

随机推荐