如何分情況給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


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