如何分情况给Dialog传入不同的样式

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章