錯誤訊息 requestFeature() must be called before adding content 表示在呼叫 setContentView() 後才嘗試請求視窗功能(如 FEATURE_CUSTOM_TITLE, FEATURE_NO_TITLE 等)。Android 視窗功能必須在佈局填充前決定,否則拋出異常。
// 錯誤順序
setContentView(R.layout.main); // 1. 先添加內容
UIHelper.setupTitleBar(this); // 2. 再請求功能 → 崩潰
// UIHelper.setupTitleBar 內部
c.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); // 此處拋出異常
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 1. 請求視窗功能(在 setContentView 之前)
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
// 或 requestWindowFeature(Window.FEATURE_NO_TITLE);
// 2. 設定佈局
setContentView(R.layout.main);
// 3. 套用自訂標題佈局(若有)
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.titlebar);
}
public class UIHelper {
public static void setupCustomTitle(Activity activity, int titleLayoutResId) {
// 呼叫端必須確保在 setContentView 前調用此方法
boolean supported = activity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
if (supported) {
activity.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, titleLayoutResId);
}
}
}
// 正確使用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
UIHelper.setupCustomTitle(this, R.layout.titlebar); // 在 setContentView 前
setContentView(R.layout.main);
}
若僅需對話框自訂標題,建議改用 DialogFragment 或 AlertDialog.Builder.setCustomTitle(View),避免 Activity 級視窗功能限制:
AlertDialog dialog = new AlertDialog.Builder(this)
.setCustomTitle(LayoutInflater.from(this).inflate(R.layout.custom_title, null))
.setView(contentView)
.create();
dialog.show();
視窗功能請求 → 佈局填充 → 功能配置
任何requestWindowFeature()、setFeatureInt()必須在setContentView()之前完成。
onPostCreate()、onStart() 中請求功能 → 太晚,會崩潰。setContentView() 導致重複添加內容。NoActionBar 再請求 FEATURE_CUSTOM_TITLE 衝突。嚴守呼叫順序,即可避免此經典異常。