我們創建一個Dialog時,需要傳入一個theme參數。源碼如下:
public Dialog(@NonNull Context context, @StyleRes int themeResId) { this(context, themeResId, true); }
有時候我們會遇到一種需求,在不同的情況下需要不同的theme。我最開始的想法是在創建Dialog的地方多傳一個參數就行了啊,形如:
if (use_theme1) { myDialog = new MyDialog(this, theme1); } else { myDialog = new MyDialog(this, theme2); }
可是一瞧,創建MyDialog的地方太多了,不覺得麻煩嗎,可不可以在MyDialog內容進行處理呢。於是想到在MyDialog的構造方法中加以判斷,形如:
public MyDialog(Context context, int theme) { if (use_theme1) { super(context, theme1); } else { super(context, theme2); } }
結果是有語法錯誤,又不行!!!後來查看源碼,看這個theme傳下去到底做了什麼,上源碼:
public Dialog(@NonNull Context context, @StyleRes int themeResId) { this(context, themeResId, true); } Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) { if (createContextThemeWrapper) { if (themeResId == 0) { final TypedValue outValue = new TypedValue(); context.getTheme().resolveAttribute(R.attr.dialogTheme, outValue, true); themeResId = outValue.resourceId; } mContext = new ContextThemeWrapper(context, themeResId); } else { mContext = context; } mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); final Window w = new PhoneWindow(mContext); mWindow = w; w.setCallback(this); w.setOnWindowDismissedCallback(this); w.setWindowManager(mWindowManager, null, null); w.setGravity(Gravity.CENTER); mListenersHandler = new ListenersHandler(this); }
Dialog內部有一個mContext,類型爲ContextThemeWrapper,創建這個mContext是就用到了theme。再看看ContextThemeWrapper的代碼,裏面有個mThemeResource,我們傳入的theme就賦值給了這個mThemeResource。然後我們發現有現成的API可以更改mThemeResource:
@Override public void setTheme(int resid) { if (mThemeResource != resid) { mThemeResource = resid; initializeTheme(); } }
既然這樣,那我何不試試在MyDialog的內部調用this.getContext.setTheme(theme)。在哪裏調用好了呢?後來在網上查找得知必須要在setContentView之前調用。上代碼:
public MyDialog(Context context, int theme) { super(context, theme); if (theme1) { this.getContext().setTheme(R.style.theme1); } else { this.getContext().setTheme(R.style.theme2); } inflate = LayoutInflater.from(context).inflate(R.layout.dialog, null); setContentView(inflate); }THE END