Spinner选中项无法刷新ListView,需基于选项值构建URL获取JSON更新列表
Solution for Spinner Selection Refreshing ListView with New JSON Data
Let's break down how to fix your issue step by step, including a reusable method to fetch data from any URL:
1. Core Setup in Your Fragment
First, ensure you have the necessary views and variables initialized in your Fragment's onCreateView:
public class YourFragment extends Fragment { private Spinner spinner; private ListView listView; private List<YourDataModel> dataList; private YourCustomAdapter listAdapter; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.your_fragment_layout, container, false); // Initialize views spinner = view.findViewById(R.id.your_spinner_id); listView = view.findViewById(R.id.your_listview_id); // Initialize data storage and adapter dataList = new ArrayList<>(); listAdapter = new YourCustomAdapter(getContext(), dataList); listView.setAdapter(listAdapter); // Set up Spinner with options and selection listener setupSpinner(); // Initial data load with default URL fetchDataFromUrl("https://your-default-api-url.com/data"); return view; } }
2. Spinner Selection Listener
Add a listener to trigger data refresh when a Spinner item is selected:
private void setupSpinner() { // Replace with your actual Spinner options List<String> spinnerOptions = Arrays.asList("Option 1", "Option 2", "Option 3"); ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, spinnerOptions); spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(spinnerAdapter); spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { String selectedValue = parent.getItemAtPosition(position).toString(); // Build your dynamic URL using the selected value String dynamicUrl = "https://your-api-base-url.com/data?filter=" + selectedValue; // Fetch new data with the updated URL fetchDataFromUrl(dynamicUrl); } @Override public void onNothingSelected(AdapterView<?> parent) { // Optional: Handle empty selection case } }); }
3. Reusable Data Fetch Method
Create a method that takes a URL, fetches JSON data, parses it, and updates the ListView:
private void fetchDataFromUrl(String url) { new FetchDataTask().execute(url); } // AsyncTask to handle background network operations (note: AsyncTask is deprecated in API 30+, consider Coroutines/RxJava for newer apps) private class FetchDataTask extends AsyncTask<String, Void, List<YourDataModel>> { @Override protected List<YourDataModel> doInBackground(String... urls) { String targetUrl = urls[0]; List<YourDataModel> newData = new ArrayList<>(); try { // Establish connection and read JSON response URL apiUrl = new URL(targetUrl); HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection(); connection.setRequestMethod("GET"); BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuilder responseBuilder = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { responseBuilder.append(line); } reader.close(); connection.disconnect(); // Parse JSON into your data model (adjust based on your JSON structure) String jsonResponse = responseBuilder.toString(); JSONObject rootObj = new JSONObject(jsonResponse); JSONArray dataArray = rootObj.getJSONArray("your_data_array_key"); for (int i = 0; i < dataArray.length(); i++) { JSONObject itemObj = dataArray.getJSONObject(i); YourDataModel item = new YourDataModel(); item.setId(itemObj.getInt("id")); item.setTitle(itemObj.getString("title")); // Add other fields from your JSON newData.add(item); } } catch (IOException | JSONException e) { e.printStackTrace(); // Show error message to user on UI thread getActivity().runOnUiThread(() -> Toast.makeText(getContext(), "Failed to load data", Toast.LENGTH_SHORT).show() ); } return newData; } @Override protected void onPostExecute(List<YourDataModel> result) { // Update data list and refresh ListView dataList.clear(); dataList.addAll(result); listAdapter.notifyDataSetChanged(); } }
4. Data Model and Custom Adapter
Define your data model and adapter to display the data in the ListView:
// Your data model class (match your JSON structure) public static class YourDataModel { private int id; private String title; // Getters and Setters public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } // Custom adapter for ListView public static class YourCustomAdapter extends ArrayAdapter<YourDataModel> { public YourCustomAdapter(Context context, List<YourDataModel> items) { super(context, 0, items); } @Override public View getView(int position, View convertView, ViewGroup parent) { // Reuse existing view if available if (convertView == null) { convertView = LayoutInflater.from(getContext()) .inflate(R.layout.your_list_item_layout, parent, false); } YourDataModel item = getItem(position); // Bind data to views in your list item layout TextView idTv = convertView.findViewById(R.id.item_id); TextView titleTv = convertView.findViewById(R.id.item_title); idTv.setText(String.valueOf(item.getId())); titleTv.setText(item.getTitle()); return convertView; } }
5. Required Permission
Add the internet permission to your AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
Key Notes
- AsyncTask Deprecation: For Android API 30+, consider using Kotlin Coroutines, RxJava, or
ExecutorServiceinstead of AsyncTask for background operations. - JSON Parsing: Adjust the parsing logic to match your actual JSON response structure (e.g., different array keys, field names).
- Error Handling: Expand the error handling to cover cases like no internet connection, invalid URL, or empty responses.
内容的提问来源于stack exchange,提问作者Sandeep Kumar
相关产品推荐
相关产品推荐

