我们创建一个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