ListView 每列包含三個 ImageButton(play、detail、buy),需對每個按鈕單獨處理點擊。
public class ThumbnailAdapter extends BaseAdapter {
private final LayoutInflater inflater;
private final List items;
private final OnItemActionListener listener; // 介面回調給 Activity/Fragment
public ThumbnailAdapter(Context ctx, List items, OnItemActionListener listener) {
this.inflater = LayoutInflater.from(ctx);
this.items = items;
this.listener = listener;
}
@Override public int getCount() { return items.size(); }
@Override public VideoItem getItem(int pos) { return items.get(pos); }
@Override public long getItemId(int pos) { return pos; }
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_item_video, parent, false);
holder = new ViewHolder();
holder.btnPlay = convertView.findViewById(R.id.btn_play);
holder.btnDetail = convertView.findViewById(R.id.btn_detail);
holder.btnBuy = convertView.findViewById(R.id.btn_buy);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final VideoItem item = getItem(position);
// 逐按鈕綁定,傳遞 position 與資料模型
holder.btnPlay.setOnClickListener(v -> listener.onPlay(item, position));
holder.btnDetail.setOnClickListener(v -> listener.onDetail(item, position));
holder.btnBuy.setOnClickListener(v -> listener.onBuy(item, position));
// 其他 UI 綁定...
return convertView;
}
static class ViewHolder {
ImageButton btnPlay, btnDetail, btnBuy;
}
public interface OnItemActionListener {
void onPlay(VideoItem item, int position);
void onDetail(VideoItem item, int position);
void onBuy(VideoItem item, int position);
}
}
findViewById,提升滑動流暢度。if (convertView == null) 分支只建立一次 ViewHolder。getView 內 **new Listener 物件** 導致大量 GC → 定義為 final 欄位或介面引用。android:focusable="false" 於按鈕,導致 ListView OnItemClickListener 搶奪焦點。wrap_content 導致項目高度不一致 → 固定高度或 match_parent。新專案建議直接用 RecyclerView + RecyclerView.Adapter,原理相同但強制 ViewHolder、支援動畫、項目動畫、預載更完善。
掌握「自訂 Adapter + ViewHolder + 逐按鈕綁定」,ListView 多按鈕互動不再頭痛。