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

如何根据州AutoCompleteTextView的选择填充城市AutoCompleteTextView?

实现州选择联动城市AutoCompleteTextView的解决方案

看起来你已经完成了基础的州和城市数据加载,只需要补上州选择后联动更新城市下拉选项的逻辑就可以了,同时还能保留用户手动输入城市的功能。下面是修改后的完整代码和关键说明:

关键修改点

  • 把edtxt_state的OnItemSelectedListener替换为OnItemClickListener(AutoCompleteTextView更适合用这个监听,避免下拉展开时的误触发)
  • 在州选中的回调里,匹配对应城市列表并更新城市AutoCompleteTextView的适配器
  • 确保城市输入框既可以自动加载联动选项,也支持用户手动输入

修改后的MainActivity.java

public class MainActivity extends AppCompatActivity {
    EditText edtxt_name_address, edtxt_email_address, edtxt_mobile_address, edtxt_alt_mob_address, edtxt_pincode, edtxt_addline1, edtxt_addline2;
    Button buttonSaveAddress;
    AutoCompleteTextView edtxt_city, edtxt_state;
    private static final String KEY_STATE = "state";
    private static final String KEY_CITIES = "cities";
    private String cities_url = "http://api.androiddeft.com/cities/cities_array.json";
    final List<State> statesList = new ArrayList<>();
    final List<String> states = new ArrayList<>();
    // 声明城市适配器,方便后续更新
    private ArrayAdapter<String> cityAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        edtxt_city = findViewById(R.id.edtxt_city);
        edtxt_state = findViewById(R.id.edtxt_state);
        loadStateCityDetails();
        
        // 初始化州的适配器
        ArrayAdapter<String> stateAdapter = new ArrayAdapter<>(this, android.R.layout.select_dialog_item, states);
        edtxt_state.setThreshold(1);
        edtxt_state.setAdapter(stateAdapter);

        // 州选择的点击监听(替换原来的OnItemSelectedListener)
        edtxt_state.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // 获取选中的州名称
                String selectedState = states.get(position);
                // 找到对应州的城市列表
                List<String> matchedCities = new ArrayList<>();
                for (State state : statesList) {
                    if (state.getStateName().equals(selectedState)) {
                        matchedCities = state.getCities();
                        break;
                    }
                }
                // 更新城市AutoCompleteTextView的适配器
                cityAdapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.select_dialog_item, matchedCities);
                edtxt_city.setThreshold(1);
                edtxt_city.setAdapter(cityAdapter);
                // 可选:自动清空之前的城市输入,避免混淆
                edtxt_city.setText("");
            }
        });

        buttonSaveAddress = findViewById(R.id.buttonSaveAddress);
        buttonSaveAddress.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                saveAddress();
            }
        });
    }

    private void loadStateCityDetails() {
        JsonArrayRequest jsArrayRequest = new JsonArrayRequest(Request.Method.GET, cities_url, null, new Response.Listener<JSONArray>() {
            @Override
            public void onResponse(JSONArray responseArray) {
                try {
                    for (int i = 0; i < responseArray.length(); i++) {
                        JSONObject response = responseArray.getJSONObject(i);
                        String state = response.getString(KEY_STATE);
                        JSONArray cities = response.getJSONArray(KEY_CITIES);
                        List<String> citiesList = new ArrayList<>();
                        for (int j = 0; j < cities.length(); j++) {
                            citiesList.add(cities.getString(j));
                        }
                        statesList.add(new State(state, citiesList));
                        states.add(state);
                    }
                    // 数据加载完成后,刷新州的适配器(如果初始化时数据还没加载完)
                    ((ArrayAdapter)edtxt_state.getAdapter()).notifyDataSetChanged();
                } catch (JSONException e) {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(), "数据解析失败", Toast.LENGTH_SHORT).show();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(getApplicationContext(), "加载数据失败:" + error.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
        MySingleton.getInstance(this).addToRequestQueue(jsArrayRequest);
    }

    private void saveAddress() {
        String city = edtxt_city.getText().toString().trim();
        String state = edtxt_state.getText().toString().trim();
        
        if (TextUtils.isEmpty(city)) {
            edtxt_city.setError("Please enter your City");
            edtxt_city.requestFocus();
            return;
        }
        if (TextUtils.isEmpty(state)) {
            edtxt_state.setError("Please enter your State");
            edtxt_state.requestFocus();
            return;
        }
        Intent profile_next = new Intent(MainActivity.this, ProfileNextActivity.class);
        startActivity(profile_next);
    }
}

State.java(无需修改,保持原样)

public class State {
    private String stateName;
    private List<String> cities;

    public State(String stateName, List<String> cities) {
        this.stateName = stateName;
        this.cities = cities;
    }

    public String getStateName() {
        return stateName;
    }

    public List<String> getCities() {
        return cities;
    }
}

额外说明

  1. 为什么用OnItemClickListener?
    AutoCompleteTextView的OnItemSelectedListener会在下拉列表展开时自动选中第一项(即使用户没点击),导致不必要的联动。而OnItemClickListener只有当用户真正点击选中某一个州时才触发,逻辑更准确。

  2. 保留手动输入能力
    代码中没有限制城市输入框的编辑权限,用户既可以选择自动加载的城市选项,也可以手动输入自定义的城市名称,完全符合你提到的电商APP类似需求。

  3. 数据加载后的适配器刷新
    因为Volley请求是异步的,初始化州适配器时可能数据还没加载完成,所以在loadStateCityDetails的onResponse末尾加上notifyDataSetChanged(),确保数据加载完成后州的下拉选项能正常显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:38:49