ListView 每行包含按鈕,需求:
getView 中正確綁定並保持位置關聯public class MyAdapter extends BaseAdapter {
private List dataList;
private OnItemActionListener listener;
static class ViewHolder {
TextView tvTitle;
Button btnAction;
int position; // 關鍵:持有當前位置
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.item_layout, parent, false);
holder = new ViewHolder();
holder.tvTitle = convertView.findViewById(R.id.tv_title);
holder.btnAction = convertView.findViewById(R.id.btn_action);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// 1. 更新位置標記(極其重要!)
holder.position = position;
// 2. 綁定數據
ItemData item = dataList.get(position);
holder.tvTitle.setText(item.title);
// 3. 按鈕點擊:傳遞精確位置
holder.btnAction.setOnClickListener(v -> {
if (listener != null) {
listener.onButtonClick(holder.position, item);
}
});
// 4. 整行點擊(可選,設置給 convertView)
convertView.setOnClickListener(v -> {
if (listener != null) {
listener.onItemClick(holder.position, item);
}
});
return convertView;
}
public interface OnItemActionListener {
void onButtonClick(int position, ItemData item);
void onItemClick(int position, ItemData item);
}
public void setOnItemActionListener(OnItemActionListener listener) {
this.listener = listener;
}
}
在 XML 布局中,給按鈕添加屬性防止行點擊攔截:
<Button
android:id="@+id/btn_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false"
android:descendantFocusability="blocksDescendants" />
或在代碼中:holder.btnAction.setFocusable(false);
adapter.setOnItemActionListener(new MyAdapter.OnItemActionListener() {
@Override
public void onButtonClick(int position, ItemData item) {
// 處理按鈕邏輯,如彈窗確認刪除
showDeleteDialog(position, item);
}
@Override
public void onItemClick(int position, ItemData item) {
// 處理行點擊,如跳轉詳情頁
startActivity(DetailActivity.newIntent(item));
}
});
新專案強烈建議使用 RecyclerView + ViewHolder,原生支援 OnClickListener 區分,配合 ItemTouchHelper 實現滑動刪除等高級交互,架構更清晰、效能更優。
ListView 按鈕與行點擊共存的核心在於:ViewHolder 持有位置 → getView 更新位置 → 綁定獨立監聽 → XML 阻止焦點衝突。這套模式經過千萬級 App 驗證,穩定可靠。若專案允許,遷移至 RecyclerView 將獲得更現代的開發體驗。