在 BaseAdapter.getView() 中為項目內 Button 設置 OnClickListener,需獲取項目位置 position。直接用外部變量 pos 會因複用導致值錯誤 (總是最後一項)。
@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;
}
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);
final int pos = position; // 必須 final 或 effectively final
holder.btnDetail.setOnClickListener(v -> {
doAction(items.get(pos)); // 直接捕獲 pos
});
注意:僅適用於 convertView == null 創建新 ViewHolder 時。複用時需重新設置監聽器更新捕獲變量,否則舊監聽器持有舊位置。
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;
}
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。