1、全屏Dialog實(shí)現(xiàn)方式
public class FullScrreenDialog extends Dialog {
public FullScrreenDialog(Context context) {
super(context);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
<!--關(guān)鍵點(diǎn)1-->
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_full_screen, null);
<!--關(guān)鍵點(diǎn)2-->
setContentView(view);
<!--關(guān)鍵點(diǎn)3-->
getWindow().setBackgroundDrawable(new ColorDrawable(0x00000000));
<!--關(guān)鍵點(diǎn)4-->
getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
}
}
- 1搀突、
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
必須在setContent(View view)
之后刀闷。 - 2、關(guān)鍵點(diǎn)3和4必須通知設(shè)置才能達(dá)到全屏的效果仰迁。
這又是為什么呢甸昏?這里先分析下關(guān)鍵點(diǎn)1。
1.1徐许、關(guān)鍵點(diǎn)1
先看下setContentView()
@Override
public void setContentView(int layoutResID) {
//...省略部分就是創(chuàng)建DecorView施蜜,把id為android.R.id.content的ContentParent添加到DecorView中。
mContentParentExplicitlySet = true;
}
在setContentView()方法的最后mContentParentExplicitlySet = true;
雌隅,接下看下getWindow().requestFeature()
@Override
public boolean requestFeature(int featureId) {
if (mContentParentExplicitlySet) {
throw new AndroidRuntimeException("requestFeature() must be called before adding content");
}
//省略代碼...
return super.requestFeature(featureId);
}
代碼很簡單翻默,mContentParentExplicitlySet為true時(shí),直接拋出異常恰起,所以
getWindow().requestFeature()
必須在setContentView()之前調(diào)用修械,對(duì)于Activity也是一樣的。
1.2检盼、關(guān)鍵點(diǎn)3和關(guān)鍵點(diǎn)4
為什么getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
不能實(shí)現(xiàn)全屏呢肯污?
這是因?yàn)槿绻辉O(shè)置background的話就會(huì)使用默認(rèn)的背景,默認(rèn)背景是含有inset標(biāo)簽構(gòu)建的吨枉,并且四周設(shè)置了邊距蹦渣,所以不能達(dá)到全屏。
其實(shí)也可以在創(chuàng)建Dialog時(shí)东羹,傳入theme來實(shí)現(xiàn)全屏剂桥,只需設(shè)置windowIsFloating為false(Activity主題默認(rèn)就是false),并設(shè)置windowBackground即可属提。
<style name="BaseDialog" parent="Theme.AppCompat.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsFloating">false</item>
</style>
1.3权逗、windowIsFloating的作用
具體原因可查看PhoneWindow中的generateLayout()方法
protected ViewGroup generateLayout(DecorView decor) {
//....
mIsFloating = a.getBoolean(R.styleable.Window_windowIsFloating, false);
int flagsToUpdate = (FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR)
& (~getForcedWindowFlags());
if (mIsFloating) {
setLayout(WRAP_CONTENT, WRAP_CONTENT);
setFlags(0, flagsToUpdate);
} else {
setFlags(FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR, flagsToUpdate);
}
}
當(dāng)mIsFloating
為true時(shí)美尸,則調(diào)用setLayout(WRAP_CONTENT, WRAP_CONTENT),所以設(shè)置mIsFloating
為false可實(shí)現(xiàn)全屏。
2斟薇、AlertDialog全屏實(shí)現(xiàn)方式
其實(shí)AlertDialog的全屏實(shí)現(xiàn)方式和Dialog基本是類似的师坎,不過需要注意的是getWindow.setLayout()需要在show()方法之后才生效。
AlertDialog alertDialog = new AlertDialog.Builder(this)
.setView(R.layout.layout_dialog_small)
.create();
alertDialog.show();
alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(0xffffffff));
alertDialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT,WindowManager.LayoutParams.MATCH_PARENT);
看下AlertDialog的show()到底做了什么操作堪滨。
public AlertDialog show() {
final AlertDialog dialog = create();
dialog.show();
return dialog;
}
代碼很簡單就是創(chuàng)建AlertDialog并show()胯陋,主要的邏輯處理在show()
中,AlertDialog.show()最終會(huì)調(diào)用Dialog中的show()
public void show() {
//....
if (!mCreated) {
dispatchOnCreate(null);
} else {
// Fill the DecorView in on any configuration changes that
// may have occured while it was removed from the WindowManager.
final Configuration config = mContext.getResources().getConfiguration();
mWindow.getDecorView().dispatchConfigurationChanged(config);
}
onStart();
mDecor = mWindow.getDecorView();
//.....
mWindowManager.addView(mDecor, l);
//....
mShowing = true;
sendShowMessage();
}
由于首次創(chuàng)建所以mCreated=false
袱箱,則調(diào)用Dialog的dispatchOnCreate()
void dispatchOnCreate(Bundle savedInstanceState) {
if (!mCreated) {
onCreate(savedInstanceState);
mCreated = true;
}
}
onCreate(savedInstanceState)
的真正實(shí)現(xiàn)在AlertDialog中的
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAlert.installContent();
}
在onCreate中會(huì)調(diào)用AlertController的installContent()
遏乔,最終會(huì)調(diào)用mWindow.setContentView()
,在分析windowIsFloating時(shí),如果windowIsFloating=false
发笔,則會(huì)調(diào)用setLayout(WRAP_CONTENT,WRAP_CONTENT)
盟萨,所以如果在show之前調(diào)用setLayout設(shè)置寬高會(huì)被覆蓋。