Adapter 本身不持有 Context,**必須從外部(通常是 Activity/Fragment)通過構造函數傳入**,然後在項目點擊事件中使用該 Context 啟動 Intent。
public class ProductListAdapter extends BaseAdapter {
private final Context context; // 持有 Context 引用
private final List<Product> dataList;
public ProductListAdapter(Context context, List<Product> dataList) {
this.context = context;
this.dataList = dataList;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.item_product, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Product product = dataList.get(position);
holder.bind(product);
// 項目點擊跳轉
convertView.setOnClickListener(v -> {
Intent intent = new Intent(context, ProductDetailActivity.class);
intent.putExtra("product_id", product.getId());
context.startActivity(intent); // 使用傳入的 Context 啟動
});
return convertView;
}
static class ViewHolder {
TextView tvName, tvPrice;
ImageView ivIcon;
ViewHolder(View view) { /* findViewById */ }
void bind(Product p) { /* setText, setImage */ }
}
}
new ProductListAdapter(this, list);在 Fragment 中用 getActivity() 或 requireContext()。ApplicationContext,需添加 Flag:intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),否則會拋異常。建議直接傳入 Activity 實例。onBindViewHolder 中對 itemView 設置 OnClickListener,使用構造函數傳入的 context。// 錯誤:嘗試在 Adapter 內部獲取 Context
// View.getContext() 可行,但不推薦,語義不清且易在非 UI 線程出問題
Intent intent = new Intent(view.getContext(), TargetActivity.class);
// 錯誤:未傳 Context 卻想 startActivity
// startActivity 是 Context 方法,Adapter 無此方法
// startActivity(intent); // 編譯錯誤
構造函數傳 Context → 持有為成員變量 → 點擊事件中 context.startActivity(intent)。這是 Android Adapter 啟動 Activity 的標準、安全、通用模式。