RecyclerView搜索异常:搜索空白重启后显示的问题排查
分析RecyclerView搜索后空白、重启后恢复的问题
这个问题我之前也碰到过,核心原因是你没正确处理FirebaseRecyclerAdapter的监听生命周期——它必须通过startListening()方法主动开启数据监听,才能从Firebase数据库加载内容到RecyclerView里。
先看你的代码细节:不管是初始化默认的adapter,还是搜索后创建新的adapter,你都只做了setAdapter(),但从来没调用过servantAdapter.startListening()。那为什么重启手机后又能正常显示?大概率是重启后Fragment的生命周期重新执行,比如onStart()方法触发了监听(可能你在其他地方写了但没注意到),或者系统读取了数据库缓存,但这都是不可靠的偶然情况。
具体问题点:
- 初始化adapter时缺少监听启动:
servantAdapter = new ServantAdapter(options); recyclerViewdatabase.setAdapter(servantAdapter); // 这里没调用 servantAdapter.startListening()
- 搜索创建新adapter时,既没停止旧adapter的监听(会导致内存泄漏),也没启动新adapter的监听:
private void firebaseSearch(String s) { FirebaseRecyclerOptions<Servant> options = ...; servantAdapter = new ServantAdapter(options); recyclerViewdatabase.setAdapter(servantAdapter); // 同样没调用 startListening() }
修复方案:
在Fragment生命周期中管理监听:
给Fragment添加onStart()和onStop()方法,统一管理adapter的启停,避免内存泄漏:@Override public void onStart() { super.onStart(); if (servantAdapter != null) { servantAdapter.startListening(); } } @Override public void onStop() { super.onStop(); if (servantAdapter != null) { servantAdapter.stopListening(); } }初始化adapter时立即启动监听:
修改初始化代码,添加监听启动://RecylerviewDatabaseServant recyclerViewdatabase = view.findViewById(R.id.recyclerViewServant); mManager = new LinearLayoutManager(getContext()); recyclerViewdatabase.setLayoutManager(mManager); FirebaseRecyclerOptions<Servant> options = new FirebaseRecyclerOptions.Builder<Servant>() .setQuery(FirebaseDatabase.getInstance().getReference().child("Servant") , Servant.class) .build(); servantAdapter = new ServantAdapter(options); recyclerViewdatabase.setAdapter(servantAdapter); // 启动监听 servantAdapter.startListening();搜索方法中正确切换adapter:
每次创建新adapter前,先停止旧adapter的监听,再启动新的:private void firebaseSearch(String s) { // 先停止旧adapter的监听,防止内存泄漏 if (servantAdapter != null) { servantAdapter.stopListening(); } FirebaseRecyclerOptions<Servant> options = new FirebaseRecyclerOptions.Builder<Servant>() .setQuery(FirebaseDatabase.getInstance() .getReference().child("Servant") .orderByChild("name").startAt(s).endAt(s + "\uf8ff"), Servant.class) .build(); servantAdapter = new ServantAdapter(options); recyclerViewdatabase.setAdapter(servantAdapter); // 启动新adapter的监听 servantAdapter.startListening(); }
这样修改后,不管是首次加载还是搜索后,adapter都会主动从数据库拉取数据,RecyclerView就不会出现空白的情况了。
内容的提问来源于stack exchange,提问作者ZalE
相关产品推荐
相关产品推荐

