You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:48:55