ArrayAdapter adapter = new ArrayAdapter<>(
this,
android.R.layout.simple_spinner_item,
HomePage.NearPlaces); // NearPlaces 可能為 null
Place.setAdapter(adapter); // Place 可能未初始化 (findViewById 失敗)
拋出 NullPointerException,堆疊指向 SpotMe.onCreate:42。
HomePage.NearPlaces 靜態字段未初始化或已清空Place = findViewById(R.id.spinner_id) 返回 null (ID 錯誤/佈局未設置)
public class SpotMe extends AppCompatActivity {
private Spinner placeSpinner;
private ArrayAdapter adapter; // 泛型用 String 或自定義模型
private List placeList = new ArrayList<>(); // 初始化空列表,避免 null
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spot_me); // 關鍵:先 setContentView
placeSpinner = findViewById(R.id.spinner_place); // 確保 ID 正確
if (placeSpinner == null) {
Log.e(TAG, "Spinner not found in layout");
return;
}
// 1. 從數據源獲取 (異步/線程安全)
loadPlacesFromSource();
// 2. 創建 Adapter (使用簡單佈局)
adapter = new ArrayAdapter<>(
this,
android.R.layout.simple_spinner_item,
placeList); // 傳入列表引用
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// 3. 綁定
placeSpinner.setAdapter(adapter);
// 4. 監聽選擇
placeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override public void onItemSelected(AdapterView> parent, View view, int pos, long id) {
String selected = placeList.get(pos);
// 處理選擇...
}
@Override public void onNothingSelected(AdapterView> parent) {}
});
}
private void loadPlacesFromSource() {
// 模擬異步加載
new Thread(() -> {
List loaded = fetchPlacesFromServerOrLocal(); // 你的數據源
runOnUiThread(() -> {
placeList.clear();
placeList.addAll(loaded);
adapter.notifyDataSetChanged(); // 關鍵:通知更新
});
}).start();
}
}
// 模型
class Place {
String id, name, address;
@Override public String toString() { return name; } // Adapter 默認顯示 toString()
}
// 自定義 Adapter (若需複雜下拉項佈局)
class PlaceAdapter extends ArrayAdapter {
PlaceAdapter(Context ctx, List list) {
super(ctx, 0, list);
}
@NonNull @Override public View getView(int pos, View cv, ViewGroup parent) {
return createView(pos, cv, parent, android.R.layout.simple_spinner_item);
}
@Override public View getDropDownView(int pos, View cv, ViewGroup parent) {
return createView(pos, cv, parent, R.layout.spinner_dropdown_item); // 自定義下拉項
}
View createView(int pos, View cv, ViewGroup parent, int layoutRes) {
if (cv == null) cv = LayoutInflater.from(getContext()).inflate(layoutRes, parent, false);
Place p = getItem(pos);
TextView tv = cv.findViewById(android.R.id.text1); // 或自定義 ID
tv.setText(p.name);
return cv;
}
}
setContentView 後再 findViewByIdnew ArrayList<>(),避免 nulladapter.notifyDataSetChanged()this (Activity) 作為 Adapter ContextonDestroy 中取消異步任務