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

Android AlertDialog 中點擊 ListView 項目關閉對話框的標準做法

     編輯:程式設計綜合問答

核心關鍵:持有 Dialog 參考,在 onItemClick 裡呼叫 dismiss()

原始碼問題在於:AlertDialog.Builder 的 show() 回傳 AlertDialog,但範例沒存起來,導致無法在 onItemClick 內關閉。

正確模式(現代寫法)

public void showSearchDialog(String[] memos) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    View view = LayoutInflater.from(this).inflate(R.layout.seach_dialog, null);
    ListView listView = view.findViewById(R.id.search_list);
    listView.setAdapter(new MyPerformanceArrayAdapter(this, memos, memo_PW));

    // 建立並持有 Dialog 實例
    AlertDialog dialog = builder
            .setTitle("Search")
            .setView(view)
            .setNegativeButton("Back", null)
            .create(); // 用 create() 不用 show()

    listView.setOnItemClickListener((parent, v, position, id) -> {
        // 處理點選邏輯...
        dialog.dismiss(); // 關鍵:持有的 dialog 實例呼叫 dismiss()
    });

    dialog.show(); // 最後才 show
}

進階:使用 DialogFragment(生命週期安全)

Activity 旋轉重建時,手持 AlertDialog 易洩漏視窗。建議改用 DialogFragment:

public class SearchDialogFragment extends DialogFragment {
    private String[] memos;
    public static SearchDialogFragment newInstance(String[] memos) {
        SearchDialogFragment f = new SearchDialogFragment();
        f.memos = memos;
        return f;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        View view = LayoutInflater.from(requireContext()).inflate(R.layout.seach_dialog, null);
        ListView lv = view.findViewById(R.id.search_list);
        lv.setAdapter(new MyPerformanceArrayAdapter(requireContext(), memos, null));

        lv.setOnItemClickListener((p, v, pos, id) -> {
            // 回傳結果給宿主
            ((OnSearchSelected) requireActivity()).onSelected(memos[pos]);
            dismiss(); // 安全關閉
        });

        return new AlertDialog.Builder(requireContext())
                .setTitle("Search")
                .setView(view)
                .setNegativeButton("Back", null)
                .create();
    }

    public interface OnSearchSelected { void onSelected(String memo); }
}

使用方式:SearchDialogFragment.newInstance(memos).show(getSupportFragmentManager(), "search")。

常見錯誤避坑

  • 在 onItemClick 裡 new AlertDialog.Builder(...).show() 建立新對話框 → 無法關閉原本那個。
  • 用 dismiss() vs cancel():dismiss() 直接關閉;cancel() 會觸發 OnCancelListener,語意上「使用者取消」才用 cancel。
  • 對話框顯示後立即旋轉螢幕 → WindowLeaked → 改用 DialogFragment 徹底解決。

總結

**持有 Dialog 實例 → 在 onItemClick 呼叫 dismiss()** 是最直接解法;專案若重視生命週期安全,**直接上 DialogFragment** 才是長久之計。

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