Android Fragment多选框显名称、绑ID并存储至Session求助
解决UpcomingRaces Fragment的多选数据关联与存储问题
我来帮你搞定这个需求!咱们一步步拆解,把从服务器拿数据、多选对话框关联ID、保存选中状态这些功能都落地。
1. 先定义数据模型
首先得有个实体类来存服务器返回的id和name,这样后续处理数据更清晰:
public class Race { private int id; private String name; // 构造方法 public Race(int id, String name) { this.id = id; this.name = name; } // Getter方法 public int getId() { return id; } public String getName() { return name; } }
2. 从服务器获取数据
这里我用Retrofit作为网络请求框架示例(如果用OkHttp或者其他框架,逻辑是相通的):
第一步:定义API接口
public interface RaceApiService { @GET("your-api-endpoint/races") // 替换成你的实际接口地址 Call<List<Race>> getUpcomingRaces(); }
第二步:在Fragment里发起请求
在UpcomingRacesFragment中,初始化Retrofit并请求数据:
public class UpcomingRacesFragment extends Fragment { private TextView mItemSelected; private List<Race> mRaceList; private boolean[] mCheckedItems; private UserSessionManager mSessionManager; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_upcoming_races, container, false); mItemSelected = view.findViewById(R.id.tv_selected_items); mSessionManager = new UserSessionManager(requireContext()); return view; } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); fetchRacesFromServer(); } private void fetchRacesFromServer() { // 初始化Retrofit Retrofit retrofit = new Retrofit.Builder() .baseUrl("your-base-url/") // 替换成你的服务器基础地址 .addConverterFactory(GsonConverterFactory.create()) .build(); RaceApiService apiService = retrofit.create(RaceApiService.class); Call<List<Race>> call = apiService.getUpcomingRaces(); call.enqueue(new Callback<List<Race>>() { @Override public void onResponse(Call<List<Race>> call, Response<List<Race>> response) { if (response.isSuccessful() && response.body() != null) { mRaceList = response.body(); // 数据拿到后,初始化多选对话框的相关数据 initMultiChoiceDialog(); // 恢复之前保存的选中状态 restoreSelectedState(); } else { // 处理请求失败的情况,比如显示Toast Toast.makeText(requireContext(), "获取数据失败", Toast.LENGTH_SHORT).show(); } } @Override public void onFailure(Call<List<Race>> call, Throwable t) { Toast.makeText(requireContext(), "网络异常:" + t.getMessage(), Toast.LENGTH_SHORT).show(); } }); } }
3. 实现多选对话框并关联ID
接下来构建多选对话框,把服务器返回的name显示出来,同时关联对应的id:
private void initMultiChoiceDialog() { // 把race的name转成CharSequence数组,用于对话框显示 CharSequence[] raceNames = new CharSequence[mRaceList.size()]; for (int i = 0; i < mRaceList.size(); i++) { raceNames[i] = mRaceList.get(i).getName(); } // 初始化选中状态数组,默认都未选中 mCheckedItems = new boolean[mRaceList.size()]; // 创建对话框 AlertDialog.Builder builder = new AlertDialog.Builder(requireContext()); builder.setTitle("选择赛事") .setMultiChoiceItems(raceNames, mCheckedItems, new DialogInterface.OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialog, int which, boolean isChecked) { // 更新选中状态数组 mCheckedItems[which] = isChecked; } }) .setPositiveButton("确认", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 收集选中的id List<Integer> selectedIds = new ArrayList<>(); StringBuilder selectedNames = new StringBuilder(); for (int i = 0; i < mRaceList.size(); i++) { if (mCheckedItems[i]) { int raceId = mRaceList.get(i).getId(); selectedIds.add(raceId); selectedNames.append(mRaceList.get(i).getName()).append(", "); } } // 更新TextView显示 if (selectedNames.length() > 0) { // 去掉最后一个逗号和空格 selectedNames.delete(selectedNames.length() - 2, selectedNames.length()); mItemSelected.setText("选中的赛事ID:" + selectedIds.toString() + "\n选中的赛事名称:" + selectedNames.toString()); } else { mItemSelected.setText("未选中任何赛事"); } // 保存选中的id到UserSessionManager mSessionManager.saveSelectedRaceIds(selectedIds); } }) .setNegativeButton("取消", null); builder.create().show(); }
4. 实现UserSessionManager存储选中ID
假设你的UserSessionManager是用SharedPreferences来管理会话数据,核心代码如下:
public class UserSessionManager { private SharedPreferences mSharedPref; private static final String KEY_SELECTED_RACE_IDS = "selected_race_ids"; public UserSessionManager(Context context) { mSharedPref = context.getSharedPreferences("user_session", Context.MODE_PRIVATE); } // 保存选中的id列表 public void saveSelectedRaceIds(List<Integer> ids) { Gson gson = new Gson(); String idsJson = gson.toJson(ids); mSharedPref.edit().putString(KEY_SELECTED_RACE_IDS, idsJson).apply(); } // 获取保存的id列表 public List<Integer> getSelectedRaceIds() { String idsJson = mSharedPref.getString(KEY_SELECTED_RACE_IDS, "[]"); Gson gson = new Gson(); Type type = new TypeToken<List<Integer>>() {}.getType(); return gson.fromJson(idsJson, type); } }
5. 恢复上次选中的状态(可选但实用)
如果需要在Fragment加载时恢复之前选中的状态,可以加这个方法:
private void restoreSelectedState() { List<Integer> savedIds = mSessionManager.getSelectedRaceIds(); if (savedIds != null && !savedIds.isEmpty() && mRaceList != null) { // 更新checkedItems数组 for (int i = 0; i < mRaceList.size(); i++) { int raceId = mRaceList.get(i).getId(); mCheckedItems[i] = savedIds.contains(raceId); } // 更新TextView显示 StringBuilder selectedNames = new StringBuilder(); for (int id : savedIds) { for (Race race : mRaceList) { if (race.getId() == id) { selectedNames.append(race.getName()).append(", "); break; } } } if (selectedNames.length() > 0) { selectedNames.delete(selectedNames.length() - 2, selectedNames.length()); mItemSelected.setText("选中的赛事ID:" + savedIds.toString() + "\n选中的赛事名称:" + selectedNames.toString()); } } }
一些注意事项
- 别忘了在
AndroidManifest.xml中添加网络权限:<uses-permission android:name="android.permission.INTERNET" /> - 网络请求一定要在子线程执行(上面用Retrofit的
enqueue已经自动处理了) - 处理服务器返回空数据的情况,避免空指针异常
- 如果你的项目里没有Gson,需要在
build.gradle中添加依赖:implementation 'com.google.code.gson:gson:2.10.1' - Retrofit的依赖也需要添加:
implementation 'com.squareup.retrofit2:retrofit:2.9.0'和implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
内容的提问来源于stack exchange,提问作者Yana Shetty
相关产品推荐
相关产品推荐

