RecyclerView条目无限重复新增,结合Firebase+定位功能的解决方案?
问题原因
- 定位更新每3-4秒触发一次
getdriver()方法,每次执行都会重新查询周边司机,查询到数据后直接追加到全局list中,没有清空上一次的旧数据 - 每次
onKeyEntered触发时都给司机节点注册一次addValueEventListener持久监听,重复注册的监听会多次回调,导致同一条司机数据被反复添加到列表 getdriver()中重复创建MyAdapter实例、重复给RecyclerView设置适配器,属于冗余逻辑,也会加剧列表刷新异常
修复方案
适配器初始化逻辑前移
只在onCreate里初始化一次适配器和布局管理器,不要每次查数据都新建,修改onCreate代码:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_recycler); r1 = findViewById(R.id.r1); // 新增适配器初始化逻辑,仅执行一次 r1.setLayoutManager(new LinearLayoutManager(this)); myAdapter = new MyAdapter(list, this); r1.setAdapter(myAdapter); client = LocationServices.getFusedLocationProviderClient(this); // 原有后续逻辑不变 ... }
同时删除getdriver()方法末尾的三行适配器初始化代码。
新增列表清空+数据去重逻辑
首先修改MyModel类,新增司机唯一标识字段用于去重:
public class MyModel { // 新增司机ID字段,对应Firebase的司机key private String driverId; // 新增对应getter方法 public String getDriverId() { return driverId; } // 修改构造方法 public MyModel(String driverId, String name, String number, String car) { this.driverId = driverId; this.name = name; this.number = number; this.car = car; } // 原有其他逻辑不变 ... }
然后修改getdriver()方法,每次查询前先清空旧数据:
private void getdriver() { // 先清空上一次查询的旧数据 list.clear(); myAdapter.notifyDataSetChanged(); // 原有后续逻辑不变 DatabaseReference driver = FirebaseDatabase.getInstance().getReference().child("Drivers Available"); ... }
最后在添加数据前新增去重判断:
@Override public void onDataChange(@NonNull DataSnapshot snapshot) { if (snapshot.exists()) { // 先判断该司机是否已经在列表中,避免重复添加 boolean isExist = false; for (MyModel item : list) { if (item.getDriverId().equals(key)) { isExist = true; break; } } if (isExist) return; Map<String, Object> map = (Map<String, Object>) snapshot.getValue(); if (map.get("Name") != null) { name = map.get("Name").toString(); } if (map.get("Number") != null) { number = map.get("Number").toString(); } if (map.get("Car") != null) { car = map.get("Car").toString(); } // 构造对象的时候传入司机唯一key list.add(new MyModel(key, name,number,car)); myAdapter.notifyDataSetChanged(); } }
替换持久监听为单次查询
如果不需要实时监听单个司机的数据变化,把addValueEventListener改成addListenerForSingleValueEvent,避免后续数据变更重复触发回调:
reff.addListenerForSingleValueEvent(new ValueEventListener() { // 原有回调逻辑保持不变 ... });
内容的提问来源于stack exchange,提问作者Meet Davda
相关产品推荐
相关产品推荐

