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

Android基于Volley实现多Spinner联动(数据来自服务器JSON)

Hey there! Since you're new to Android development, let's break down exactly how to build this 3-spinner联动 feature with Volley—step by step, so it's easy to follow.

Step 1: Add Volley Dependency & Internet Permission

First, you need to include Volley in your project. Open your module-level build.gradle file and add this dependency:

dependencies {
    implementation 'com.android.volley:volley:1.2.1'
}

Then, add the internet permission to your AndroidManifest.xml (Volley needs this to make network calls):

<uses-permission android:name="android.permission.INTERNET" />
Step 2: Define Data Models

To make handling JSON responses easier, create simple data classes to represent your job types, tasks, and prices. Here's a Kotlin example (Java works similarly—just use POJOs):

// Represents a job type (e.g., "Plumber")
data class JobType(val id: String, val name: String)

// We'll pair tasks and prices, so we can load them together
data class TaskPrice(val taskName: String, val price: String)
Step 3: Set Up Your Layout

Create a layout with three spinners in your activity XML (e.g., activity_main.xml):

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <Spinner
        android:id="@+id/spinner_job_type"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:prompt="@string/select_job_type"/>

    <Spinner
        android:id="@+id/spinner_task"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:prompt="@string/select_task"/>

    <Spinner
        android:id="@+id/spinner_price"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:prompt="@string/view_price"/>
</LinearLayout>
Step 4: Implement the Logic in Your Activity

Now, let's wire up the spinners with Volley to load data and handle the联动. Here's the full activity code with comments explaining each part:

import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Spinner
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.android.volley.Request
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import org.json.JSONArray
import org.json.JSONObject

class MainActivity : AppCompatActivity() {
    private lateinit var jobTypeSpinner: Spinner
    private lateinit var taskSpinner: Spinner
    private lateinit var priceSpinner: Spinner
    private lateinit var requestQueue: Volley.RequestQueue
    // Store tasks and prices to sync them later
    private val taskList = mutableListOf<String>()
    private val priceList = mutableListOf<String>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Initialize all spinners
        jobTypeSpinner = findViewById(R.id.spinner_job_type)
        taskSpinner = findViewById(R.id.spinner_task)
        priceSpinner = findViewById(R.id.spinner_price)

        // Set up Volley's request queue (this handles all network calls)
        requestQueue = Volley.newRequestQueue(this)

        // Load the first spinner with job types from your server
        loadJobTypes()

        // Listen for selections on the job type spinner
        jobTypeSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                // Get the selected job type's ID (use this to fetch matching tasks/prices)
                val selectedJob = parent?.getItemAtPosition(position) as JobType
                loadTasksAndPrices(selectedJob.id)
            }

            override fun onNothingSelected(parent: AdapterView<*>?) {
                // Clear the other spinners if no job is selected
                taskList.clear()
                priceList.clear()
                updateTaskAndPriceSpinners()
            }
        }

        // Optional: Sync task and price selections (so choosing a task auto-selects its price)
        taskSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                priceSpinner.setSelection(position)
            }

            override fun onNothingSelected(parent: AdapterView<*>?) {}
        }
    }

    private fun loadJobTypes() {
        // Replace this URL with your actual server endpoint for job types
        val jobTypeUrl = "https://your-server.com/api/get-job-types"
        val stringRequest = StringRequest(
            Request.Method.GET, jobTypeUrl,
            { response ->
                // Parse the JSON response into a list of JobType objects
                val jobTypes = mutableListOf<JobType>()
                val jsonArray = JSONArray(response)
                for (i in 0 until jsonArray.length()) {
                    val jobObj = jsonArray.getJSONObject(i)
                    val jobId = jobObj.getString("id") // Match your backend's JSON key
                    val jobName = jobObj.getString("name")
                    jobTypes.add(JobType(jobId, jobName))
                }
                // Attach the list to the job type spinner
                val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, jobTypes)
                adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
                jobTypeSpinner.adapter = adapter
            },
            { error ->
                // Show an error message if the request fails
                Toast.makeText(this, "Failed to load job types: ${error.message}", Toast.LENGTH_SHORT).show()
            }
        )
        // Add the request to Volley's queue to execute it
        requestQueue.add(stringRequest)
    }

    private fun loadTasksAndPrices(jobId: String) {
        // Replace this URL with your endpoint that takes a job ID and returns tasks/prices
        val taskPriceUrl = "https://your-server.com/api/get-tasks?jobId=$jobId"
        val stringRequest = StringRequest(
            Request.Method.GET, taskPriceUrl,
            { response ->
                // Clear old data before loading new
                taskList.clear()
                priceList.clear()
                val jsonArray = JSONArray(response)
                for (i in 0 until jsonArray.length()) {
                    val taskPriceObj = jsonArray.getJSONObject(i)
                    val taskName = taskPriceObj.getString("task_name") // Match your JSON key
                    val price = taskPriceObj.getString("price")
                    taskList.add(taskName)
                    priceList.add(price)
                }
                // Update the task and price spinners with new data
                updateTaskAndPriceSpinners()
            },
            { error ->
                Toast.makeText(this, "Failed to load tasks/prices: ${error.message}", Toast.LENGTH_SHORT).show()
                // Clear old data to avoid showing stale info
                taskList.clear()
                priceList.clear()
                updateTaskAndPriceSpinners()
            }
        )
        requestQueue.add(stringRequest)
    }

    private fun updateTaskAndPriceSpinners() {
        // Update task spinner
        val taskAdapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, taskList)
        taskAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        taskSpinner.adapter = taskAdapter

        // Update price spinner
        val priceAdapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, priceList)
        priceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        priceSpinner.adapter = priceAdapter
    }
}
Key Notes to Remember
  • Replace Server URLs & JSON Keys: Make sure the URLs match your backend endpoints, and the JSON field names (like "id", "name", "task_name") exactly match what your server returns.
  • Simplify JSON Parsing (Optional): If you don't want to manually parse JSON, you can use libraries like Gson or Moshi to convert JSON directly into your data classes—this saves time and reduces errors.
  • Error Handling: The code includes basic error handling with Toasts, but you can expand this (e.g., showing a retry button) for better user experience.

Hope this helps you get your spinner联动 up and running smoothly!

内容的提问来源于stack exchange,提问作者amal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:11:00