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

Android ListView 獲取點擊項位置:setTag/View.getId 在 getView 中綁定位置

     編輯:程式設計綜合問答

問題

在 BaseAdapter.getView() 中為項目內 Button 設置 OnClickListener,需獲取項目位置 position。直接用外部變量 pos 會因複用導致值錯誤 (總是最後一項)。

方案一:View.setTag 綁定位置 (推薦)


@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.list_layout, parent, false);
        holder = new ViewHolder(convertView);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    // 關鍵:為 Button 綁定位置
    holder.btnDetail.setTag(position); // 或 holder.btnDetail.setId(position)
    
    holder.btnDetail.setOnClickListener(v -> {
        int pos = (Integer) v.getTag(); // 獲取綁定的位置
        // 或 int pos = v.getId(); 若用 setId
        TaskItem item = items.get(pos);
        // 業務邏輯...
    });

    holder.bind(items.get(position));
    return convertView;
}

方案二:ViewHolder 持有位置 (需在 bind 時更新)


class ViewHolder {
    Button btnDetail;
    int position; // 當前綁定位置
    
    void bind(TaskItem item, int pos) {
        this.position = pos;
        btnDetail.setOnClickListener(v -> {
            // 使用 this.position
            doAction(items.get(this.position));
        });
    }
}

// getView 中
holder.bind(items.get(position), position);

方案三:Lambda 捕獲 final 變量 (Java 8+)


final int pos = position; // 必須 final 或 effectively final
holder.btnDetail.setOnClickListener(v -> {
    doAction(items.get(pos)); // 直接捕獲 pos
});

注意:僅適用於 convertView == null 創建新 ViewHolder 時。複用時需重新設置監聽器更新捕獲變量,否則舊監聽器持有舊位置。

最佳實踐:方案一 (setTag) 最通用、無版本限制


static class ViewHolder {
    Button btnDetail;
    TextView tvTitle;
    ViewHolder(View v) {
        btnDetail = v.findViewById(R.id.button_text);
        tvTitle = v.findViewById(R.id.list_text);
    }
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.list_layout, parent, false);
        holder = new ViewHolder(convertView);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    // 核心:綁定位置到 Button
    holder.btnDetail.setTag(position);
    holder.btnDetail.setOnClickListener(v -> {
        int pos = (Integer) v.getTag();
        TaskItem item = items.get(pos);
        // 處理點擊...
    });

    holder.tvTitle.setText(items.get(position).title);
    return convertView;
}

RecyclerView 同理:ViewHolder.getAdapterPosition()


class VH extends RecyclerView.ViewHolder {
    Button btn;
    VH(View v) {
        super(v);
        btn = v.findViewById(R.id.btn);
        btn.setOnClickListener(view -> {
            int pos = getAdapterPosition(); // 關鍵:實時獲取正確位置
            if (pos != RecyclerView.NO_POSITION) {
                onItemClick(items.get(pos));
            }
        });
    }
}

優勢:getAdapterPosition() 自動處理動畫/佈局變化中的位置偏移,無需手動綁定 Tag。

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