如何通过URL实现多个Spinner联动加载数据?
我来帮你搞定这个联动Spinner的需求!这在Android开发里是很常见的场景,下面我给你一步步拆解实现方案:
实现步骤拆解
1. 准备布局文件
先在XML布局中定义两个Spinner组件,分别对应部门和缺陷选择:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <Spinner android:id="@+id/spinner_department" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="选择部门"/> <Spinner android:id="@+id/spinner_deficiency" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="选择缺陷" android:layout_marginTop="16dp"/> </LinearLayout>
2. 创建数据模型类
为了方便处理接口返回的数据,创建两个简单的实体类来存储部门和缺陷的ID与名称:
// 部门数据模型 public class Department { private int id; private String name; public Department(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public String getName() { return name; } // Spinner会自动调用toString显示选项文本 @Override public String toString() { return name; } } // 缺陷数据模型 public class Deficiency { private int id; private String name; public Deficiency(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public String getName() { return name; } @Override public String toString() { return name; } }
3. 封装网络请求工具
这里用OkHttp来处理HTTP请求(需要先在build.gradle中添加OkHttp依赖),写一个简单的工具类:
import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import java.io.IOException; public class NetworkUtil { private static final OkHttpClient client = new OkHttpClient(); // 同步请求,必须在子线程调用 public static String get(String url) throws IOException { Request request = new Request.Builder() .url(url) .build(); try (Response response = client.newCall(request).execute()) { return response.body().string(); } } }
4. 实现联动逻辑
在Activity/Fragment中初始化Spinner,加载部门数据,并设置选中监听来触发缺陷数据的加载:
import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.Spinner; import android.widget.Toast; import android.widget.AdapterView; import android.view.View; import androidx.appcompat.app.AppCompatActivity; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private Spinner spinnerDepartment; private Spinner spinnerDeficiency; private List<Department> departmentList = new ArrayList<>(); private ArrayAdapter<Department> departmentAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); spinnerDepartment = findViewById(R.id.spinner_department); spinnerDeficiency = findViewById(R.id.spinner_deficiency); // 初始化部门Spinner的适配器 departmentAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, departmentList); departmentAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerDepartment.setAdapter(departmentAdapter); // 加载部门数据 loadDepartments(); // 设置部门选中监听,联动加载缺陷数据 spinnerDepartment.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { Department selectedDept = departmentList.get(position); loadDeficiencies(selectedDept.getId()); } @Override public void onNothingSelected(AdapterView<?> parent) { // 未选中时清空缺陷Spinner spinnerDeficiency.setAdapter(null); } }); } // 加载部门数据 private void loadDepartments() { new Thread(() -> { try { String url = "http://182.18.163.39/m/def.php?issue=1"; String response = NetworkUtil.get(url); // 解析接口返回的JSON数组(请根据实际返回格式调整) JSONArray jsonArray = new JSONArray(response); departmentList.clear(); for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); int deptId = jsonObject.getInt("id"); String deptName = jsonObject.getString("name"); departmentList.add(new Department(deptId, deptName)); } // 回到主线程更新UI runOnUiThread(() -> departmentAdapter.notifyDataSetChanged()); } catch (IOException | JSONException e) { e.printStackTrace(); runOnUiThread(() -> Toast.makeText(MainActivity.this, "加载部门数据失败", Toast.LENGTH_SHORT).show()); } }).start(); } // 根据部门ID加载缺陷数据 private void loadDeficiencies(int deptId) { new Thread(() -> { try { String url = "http://182.18.163.39/m/def.php?issue=2&dept=" + deptId; String response = NetworkUtil.get(url); // 解析缺陷数据的JSON数组(请根据实际返回格式调整) JSONArray jsonArray = new JSONArray(response); List<Deficiency> deficiencyList = new ArrayList<>(); for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); int defId = jsonObject.getInt("id"); String defName = jsonObject.getString("name"); deficiencyList.add(new Deficiency(defId, defName)); } // 回到主线程更新缺陷Spinner runOnUiThread(() -> { ArrayAdapter<Deficiency> deficiencyAdapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_spinner_item, deficiencyList); deficiencyAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerDeficiency.setAdapter(deficiencyAdapter); }); } catch (IOException | JSONException e) { e.printStackTrace(); runOnUiThread(() -> Toast.makeText(MainActivity.this, "加载缺陷数据失败", Toast.LENGTH_SHORT).show()); } }).start(); } }
5. 关键注意事项
- 记得在
AndroidManifest.xml中添加网络权限:<uses-permission android:name="android.permission.INTERNET"/> - 如果接口返回的JSON字段和示例不一致,需要调整解析逻辑中的字段名
- 可以用协程、Retrofit等替代子线程+
runOnUiThread,让代码更简洁 - 建议添加加载状态提示(比如ProgressBar),提升用户体验
内容的提问来源于stack exchange,提问作者chanduuu
相关产品推荐
相关产品推荐

