點擊 GridView 項目時發生 `NullPointerException`,Logcat 指向 `OnItemClickListener` 內部。程式碼片段:
GridView list = findViewById(R.id.list);
MyAdapter gAdapter = new MyAdapter(dev_list, this);
list.setAdapter(gAdapter);
final Integer[] images = {R.id.on, R.id.off, R.id.voice};
dev_list.setOnItemClickListener(...); // 問題行
public class MainActivity extends FragmentActivity {
private GridView gridView;
private MyAdapter adapter;
private List<Device> deviceList; // 假設資料模型
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
gridView = findViewById(R.id.list);
deviceList = loadDevices(); // 從資料庫/網路載入
// 正確:傳入資料集合與 Context
adapter = new MyAdapter(deviceList, this);
gridView.setAdapter(adapter);
// 正確:對 gridView 設定監聽器
gridView.setOnItemClickListener((parent, view, position, id) -> {
Device device = deviceList.get(position);
// 依裝置屬性決定行為,而非死板陣列索引
handleDeviceClick(device);
});
}
private void handleDeviceClick(Device device) {
String msg;
switch (device.getType()) {
case ON: msg = "說話"; break;
case OFF: msg = "停止"; break;
case VOICE: msg = "聽話"; break;
default: msg = "未知"; break;
}
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
}
| 原始錯誤 | 修正做法 | 理由 |
|---|---|---|
| `dev_list.setOnItemClickListener` | `gridView.setOnItemClickListener` | 監聽器必須綁定在實際顯示的 View 上 |
| `new MyAdapter(dev_list, this)` | `new MyAdapter(deviceList, this)` | Adapter 需要資料集合,第一參數通常為 List<T> |
| `images[position]` 硬編碼 | 從資料模型 `device.getType()` 取得 | 資料驅動 UI,解耦合順序依賴 |
| 未檢查 `deviceList` 空值 | 載入資料後檢查 `isEmpty()` | 防止 NPE 與空白列表 |