首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android Adapter 中啟動 Activity:傳遞 Context 是關鍵

     編輯:程式設計疑難解答

核心原則

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 */ }
    }
}

關鍵注意點

  • Context 來源: 在 Activity 中 new ProductListAdapter(this, list);在 Fragment 中用 getActivity() 或 requireContext()。
  • 內存洩漏防範: Adapter 持有 Context 引用通常安全,因為 Adapter 生命週期綁定 RecyclerView/ListView,隨 Activity 銷毀而釋放。**切勿**在 Adapter 中持有對 Activity 的強引用超出其生命週期(如存入單例、靜態變量)。
  • 非 Activity Context 啟動 Activity: 若傳入的是 ApplicationContext,需添加 Flag:intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),否則會拋異常。建議直接傳入 Activity 實例。
  • RecyclerView 寫法同理: 在 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 的標準、安全、通用模式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved