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

Android GridView Adapter 子控件顯示/隱藏:正確使用 View.GONE 與 View.INVISIBLE

     編輯:程式設計綜合問答

問題

在 `getView()` 中呼叫 `viewHolder.ivLogo.setVisibility(View.VISIBLE)` 無效,控件不隱藏/顯示。

原因與解決

  1. View 重用機制**:`convertView` 被重用時,子控件保留**上一次的可見狀態**。**必須在每次 `getView` 明確設定** `VISIBLE`/`INVISIBLE`/`GONE`,不能只設定其中一種情況。
  2. 正確常數**:
    • `View.VISIBLE` (0) - 顯示
    • `View.INVISIBLE` (4) - **隱藏但佔據佈局空間**
    • `View.GONE` (8) - **隱藏且不佔空間** (佈局當作不存在)

正確範例

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.grid_item, parent, false);
        holder = new ViewHolder();
        holder.ivLogo = convertView.findViewById(R.id.iv_logo);
        holder.tvName = convertView.findViewById(R.id.tv_name);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    ItemData item = getItem(position);
    holder.tvName.setText(item.name);

    // 關鍵:根據條件**明確設定兩種狀態**
    if (item.showLogo) {
        holder.ivLogo.setVisibility(View.VISIBLE);
        holder.ivLogo.setImageResource(item.logoRes);
    } else {
        holder.ivLogo.setVisibility(View.GONE); // 或 INVISIBLE
    }

    return convertView;
}

常見錯誤

// ❌ 錯誤:只處理 true 情況,false 時沒有重置,導致重用時殘留上一個 item 的狀態
if (item.showLogo) {
    holder.ivLogo.setVisibility(View.VISIBLE);
}
// 缺少 else 分支

進階:動畫切換

// 使用 ViewPropertyAnimator (API 12+)
if (show) {
    holder.ivLogo.setAlpha(0f);
    holder.ivLogo.setVisibility(View.VISIBLE);
    holder.ivLogo.animate().alpha(1f).setDuration(200).start();
} else {
    holder.ivLogo.animate().alpha(0f).setDuration(200)
        .withEndAction(() -> holder.ivLogo.setVisibility(View.GONE))
        .start();
}

**核心原則**:`getView` 中**每個條件分支都要完整設定可見狀態**,配合 `ViewHolder` 複用,即可穩定控制子控件顯示/隱藏。

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