卧铺巴士订票App切换上下层时座位选择数据丢失问题求助
问题分析与解决方案
你的问题很典型:每次切换上下层时,你都重新创建了全新的SeatDetails列表和SeatAdapter,这直接导致之前选中的座位状态完全丢失——因为新生成的列表里所有座位的isSelected都是默认的false,自然看不到之前的选择。
核心问题点
在RadioGroup的切换回调里,你每次都执行了:
seatAdapter = new SeatSelectionSleeper.SeatAdapter(SeatSelectionSleeper.this, loadBustListSeats()); recyclerView.setAdapter(seatAdapter);
loadBustListSeats()会返回一个全新的ArrayList<SeatDetails>,所有座位的选中状态都是初始值,之前的选择根本没被保存下来。
修复方案
我们需要持久化保存上下层的座位数据源,只在初始化时加载一次,切换时复用已有列表;同时避免每次切换都新建Adapter,确保选中状态能被正确保留。
步骤1:定义成员变量保存上下层数据源
在SeatSelectionSleeper类里添加两个成员变量,专门保存上下层的座位列表和对应的Adapter:
// 新增:分别保存上下层的座位数据源,只初始化一次 private List<SeatDetails> lowerSeatList; private List<SeatDetails> upperSeatList; // 新增:分别维护上下层的Adapter,避免重复创建 private SeatAdapter lowerSeatAdapter; private SeatAdapter upperSeatAdapter;
步骤2:初始化时一次性加载上下层数据
在onCreate方法里,提前加载好上下层的座位列表,并创建对应的Adapter,而不是切换时才生成:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_seat_selection_sleeper); RadioGroup radioGroup = (RadioGroup) findViewById(R.id.busDeckSelectionButtons); final RelativeLayout driver = (RelativeLayout) findViewById(R.id.driver); seatIcon = BitmapFactory.decodeResource(this.getResources(), R.drawable.sleeping_available); seatSelect = BitmapFactory.decodeResource(this.getResources(), R.drawable.sleeper_select); recyclerView = (RecyclerView) findViewById(R.id.recycler); recyclerViewupper = (RecyclerView) findViewById(R.id.recyclerupper); layoutManager = new GridLayoutManager(this, 4); layoutManagerUpper = new GridLayoutManager(this, 4); recyclerView.setLayoutManager(layoutManager); recyclerViewupper.setLayoutManager(layoutManagerUpper); // 初始化上下层数据源和Adapter,只执行一次 lowerSeatList = loadBustListSeats(); lowerSeatAdapter = new SeatAdapter(this, lowerSeatList); recyclerView.setAdapter(lowerSeatAdapter); upperSeatList = loadBustListSeatsUpper(); upperSeatAdapter = new SeatAdapter(this, upperSeatList); recyclerViewupper.setAdapter(upperSeatAdapter); radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId){ case R.id.lowerDeck: driver.setVisibility(View.VISIBLE); recyclerView.setVisibility(View.VISIBLE); recyclerViewupper.setVisibility(View.GONE); // 直接复用已有的Adapter和数据源,不需要重新创建 break; case R.id.upperDeck: driver.setVisibility(View.GONE); recyclerView.setVisibility(View.GONE); recyclerViewupper.setVisibility(View.VISIBLE); // 同样复用已有的Adapter和数据源 break; } } }); }
步骤3:确保Adapter的选中状态更新能同步到数据源
你的SeatAdapter应该在用户点击座位时,直接修改对应SeatDetails对象的isSelected属性,然后调用notifyItemChanged更新UI。比如Adapter的onBindViewHolder方法可以这样写:
// 示例:SeatAdapter的onBindViewHolder实现 @Override public void onBindViewHolder(ViewHolder holder, int position) { SeatDetails seat = seatDetailsList.get(position); if(seat.isBlank){ holder.seatView.setVisibility(View.INVISIBLE); } else { holder.seatView.setVisibility(View.VISIBLE); // 根据isSelected状态设置对应图标 holder.seatView.setImageBitmap(seat.isSelected ? seatSelect : seatIcon); // 处理座位点击事件 holder.seatView.setOnClickListener(v -> { // 切换当前座位的选中状态 seat.setSelected(!seat.isSelected); // 通知Adapter更新该位置的UI notifyItemChanged(position); // 这里可以同步更新页面上的选中座位编号、票价等信息 updateSelectedSeatInfo(); }); } }
为什么这样能解决问题?
- 上下层的数据源列表只在初始化时创建一次,之后切换时复用同一个列表,座位的
isSelected状态会被持久保存。 - Adapter也只创建一次,切换时只是显示/隐藏对应的RecyclerView,不会重新渲染,之前的选中状态自然能保留。
这样修改后,你切换上下层再切回来,之前选中的座位就会正常显示了。
内容的提问来源于stack exchange,提问作者pranali dilip gaikwad
相关产品推荐
相关产品推荐

