Activity内Fragment复用layout冲突

来源:互联网 发布:轻而易举软件的优缺点 编辑:程序博客网 时间:2024/06/03 17:52

Activity内Fragment复用layout冲突

之前用到一个页面通过ViewPage切换两个Fragment。由于布局相似,两个fragment就用了同一个layout。布局内有RecyclerView实现的刷新加载(重写SwipeRefreshLayout),出现的问题是网络请求回来的数据再次通过adapter刷新数据时会报RecyclerView﹕ No adapter attached; skipping layout错误。
关于这个错误,我在网上搜了一下,有的人说实际上使用没问题,有的人说列表不能正常显示了,总之没有找到解决方案。我这边的现象是第一个列表即使有数据也不现实;只有第二个列表会有数据,且能正常刷新。然后就有好多人抱怨RecyclerView的问题,说这个不好用等。其实这个不是控件的问题,而且获取布局的时候出了问题。
我相信类似问题发生的朋友们获取控件id的时候都是用的Activity.findViewById(int id)方式,这就是问题所在。ActivityFragment所嵌入的Activity,这种方式获取的控件是通过Activity的,并非Fragment的,所以Fragment1获取一次,之后Fragment2再获取一次(Fragment2通常后加载),本质都是Activity获取两次该控件。此时Fragment1的所指的控件就是Fragment2通过Activity获取的控件,Fragment1的刷新数据用的是Fragment1内部的adapter1,但是这个控件其实已经设置的是Fragment2的adapter2了,所以会报该adapter1未被绑定的错误。
原因知道了,解决方法也就有了。既然是Activity获取控件id导致的问题,那我们就不让activity获取,让控件绑定到Fragment内部即可。所以Fragment内部获取控件我们通常使用view即可解决问题。
不光是RecyclerView,所有控件在Fragment中都需要通过view来绑定才能保证绑定该控件在该Fragment。
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {    view = inflater.inflate(R.layout.fragment, null);    return view;}
错:
listView = (ListView) getActivity().findViewById(R.id.listView);
对:
listView = (ListView) view.findViewById(R.id.listView);

写了个Demo
0 0
原创粉丝点击