为什么卫星菜单在设置actionbar高度设置不能再frament中显示

3195人阅读
Android(20)
Fragment的使用
第一步:我们需要一个空的Activity并继承ActionBarActivity
第二步:创建一个Fragment,怎么创建一个Fragment呢,先创建一个layout命名FragmentMain,随后创建对应的java文件,命名MainFragment,文件的命名我们通常以Fragment开头。对应的java文件必须继承Fragment,注意导入的包,要是android.support.v4.app.Fragment这个包,随后重写onCreatView这个方法。
第三步:创建另一个Fragment,先创建一个layout命名FragmentAnother,随后创建对应的java文件,命名AnotherFragment,文件的命名我们通常以Fragment开头。对应的java文件必须继承Fragment,注意导入的包,要是android.support.v4.app.Fragment这个包,随后重写onCreatView这个方法。
第四步:我们需要在Fragment所呈现的Activity上设置,当MainActivity创建的时候进行初始化。首先判断一下Activiyt的当前状态,savedInstanceState==null时执行Fragment初始代码,代码如下:
public class MainActivity extends ActionBarActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null){
getSupportFragmentManager().beginTransaction().add(R.id.container,new MainFragment()).commit();
用getSupportFragmentManager方法获取到Fragment的管理器,随后beginTransaction方法开启事务,添加相对于的fragment,然后commit提交,add第一个参数表示其父组件,第二个就是需要展现的Fragment的了
第五步:然后我们开始配置MianFragment这个java文件,不进行配置的话,即使Activity打开了,Fragment也没有任何内容,第二步有说到,我们需要重写onCreatView这个方法,这个方法有个返回值,将Fragment返回出去,也就是要将FragmentMain这个布局文件返回出去,代码如下:
public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_main,container,false);
到这里,我们启动APP即可显示第一个Fragment了,如何做到Fragment来切换呢
第六步:在主Fragment中添加一个按钮,同来切换到另一个Fragment,此时我们就需要在第五步的onCreatView方法中添加代码了,代码如下:
public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_main,container,false);
Button btnStart = (Button) root.findViewById(R.id.btnStartAnthoerFragment);
btnStart.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
getFragmentManager().beginTransaction().addToBackStack(null).replace(R.id.container,new AnotherFragment()).commit();
注意:这里的findViewById需要在root下引用,因为这个按钮在Fragment布局当中
然后为这个按钮设置事件侦听。如何实现切换Fragment呢,首先调用getFragmentManager方法获取Fragment管理器,然后开启事务beginTransaction这个方法。
注意:addToBackStack方法是用来设置返回键可操作Fragment,从而返回到上一个Fragment,如果不设置,在跳转到第二个Fragment时按返回键会退出程序,这个方法可根据实际要求添加或舍去。
之前我们用的是add方法来添加Fragment使其显示,这里不能使用add方法了,需要使用replace方法来替换原有Fragment,然后commit提交。
第七步:随后我们就要配置第二个Fragment的java文件AnthorFragment这个文件了,和第五步差不多,要让第二个Fragment显示出来,必须要让他返回出去,代码如下:
public class AnotherFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_another,container,false);
到这里我们就能显示主Fragment并点击上面的按钮跳转到第二个Fragment了,并且按返回键可以跳回第一个Fragment,有的时候我们需要添加返回按钮,并不是返回键,返回按钮怎么设置呢,这里就需要在第二个Fragment下也就是AnotherFragment下添加代码了,首先要给其设置一个返回按钮,然后通过findViewById找到,代码如下:
public class AnotherFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_another,container,false);
Button btnBack = (Button) view.findViewById(R.id.btnBack);
btnBack.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
getFragmentManager().popBackStack();
为这个按钮设置侦听事件,在按钮按下时调用getFragmentManager获取到Fragment管理器,然后调用popBackStack方法即可返回到上一个Fragment了,值得注意的是:上一个Fragment需要设置addToBackStack方法添加到任务栈里面去。到这里简单的Fragment就已经完成了。
By:Oak先生
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:43181次
排名:千里之外
原创:20篇
评论:54条
(1)(4)(8)(10)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'DialogFragment的使用与底层绘制 - dialogfragment-windowmanager-dialog - ITkeyowrd
DialogFragment的使用与底层绘制
请尊重他人劳动成果,请勿随意剽窃,转载请注明,谢谢! 转载请注明出处:
& & DialogFrament是一类特定的Fragment,会将视图绘制在Activity视图的上方。一般使用场景就是展示一个警示对话框,确认对话框。使用DialogFragment而不是直接使用Dialog是一种比较推荐的方式。如果直接使用Dialog那么Dialog的生命周期是需要我们自己手动去管理的,而对于DialogFragment,它将自身交给FragmentManager进行管理,与Activity生命周期一致。比如当Activity销毁时,此时如果存在对话框,那么系统会自动销毁该对话框。而如果使用Dialog,很可能Activity已经销毁而Dialog依然存在,造成系统错误,程序出现异常。本文的大体脉络和之前博客一致,首先介绍DialogFragment如何在应用中使用,最后分析DialogFragment是如何一步一步的被绘制的屏幕上面的。
一、重写一个类继承自android.support.v4.app.DialogFragment
对于Dialog准备采用自定义布局的需要重写onCreateView、onViewCreated方法
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.dialog_fragment_profile, container);
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//view中的控件进行一系列初始化
} 对于准备才用Android那几种内置的Dialog的需要只要重写onCreateDialog方法
public Dialog onCreateDialog(Bundle savedInstanceState) {
String title = getArguments().getString(&title&); //之前通过setArguments传入的参数
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
alertDialogBuilder.setTitle(title);
alertDialogBuilder.setMessage(&Are you sure?&);
alertDialogBuilder.setPositiveButton(&OK&,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// on success
alertDialogBuilder.setNegativeButton(&Cancel&, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
return alertDialogBuilder.create();
二、定义DialogFragment的样式 DialogFragment是动态创建的,不是在xml布局文件中定义的。因此它的样式基本上都是通过所属Context的theme来指定的。下面是一个简单范例,内容出现在工程项目中的style.xml文件中。
&style name=&AppTheme& parent=&Theme.AppCompat.Light&&
&!-- Apply default style for dialogs --&
&item name=&android:dialogTheme&&@style/AppDialogTheme&/item&
&style name=&EvanBaseDialogTheme& parent=&Theme.AppCompat.Light.Dialog&&
&!--此处的值也控制ActionBar背景--&
&item name=&colorPrimary&&@color/colorPrimary&/item&
&!--此处的值也控制ActionBar上面显示电量、信号那行视图的背景--&
&item name=&colorPrimaryDark&&@color/colorPrimaryDark&/item&
&!--控制比如editText被选中状态下下面那条线的颜色--&
&item name=&colorAccent&&@color/red&/item&
&!--控制比如editText中长按选中的那部分文字的颜色,一般对其进行复制粘贴操作--&
&item name=&android:textColorHighlight&&@color/purple&/item&
&!--控制比如editText正常状态下下面那条线的颜色--&
&item name=&colorControlNormal&&@color/white&/item&
&!-- Define window properties as desired --&
&item name=&android:windowNoTitle&&false&/item&
&item name=&android:windowTitleStyle&&@style/EvanBaseDialogWindowTitle&/item&
&item name=&android:windowFullscreen&&false&/item&
&item name=&android:windowIsFloating&&true&/item&
&item name=&android:windowCloseOnTouchOutside&&true&/item&
&!--此处设置为真则背景是灰色,没有阴影效果--&
&item name=&android:windowIsTranslucent&&true&/item&
&!--整个对话框的背景颜色--&
&item name=&android:windowBackground&&@drawable/white_corners_background&/item&
&style name=&EvanBaseDialogWindowTitle&
parent=&Base.DialogWindowTitle.AppCompat&&
&item name=&android:layout_gravity&&center&/item&
&item name=&android:gravity&&center&/item&
&!--整个title部分的背景颜色--&
&item name=&android:background&&@color/white&/item&
&!--title文字显示的样子 大小等--&
&item name=&android:textAppearance&&@style/EvanBaseDialogWindowTitleText&/item&
&style name=&EvanBaseDialogWindowTitleText& parent=&@android:style/TextAppearance.DialogWindowTitle&&
&item name=&android:textSize&&@dimen/big_textSize&/item&
&/style& 三、Activity中创建DialogFragment对象,并显示出来 &
FragmentManager fm = mActivity.getSupportFragmentManager();
MyDialogFragment mDialog = MyDialogFragment.newInstance(&Some title&); //DialogFragment的创建一般都是通过getInstance方法创建。
mDialog.show(fm, &fragment_tag&);
四、其它DialogFragment的简单使用 AlertDialog:可以修改的内容有一个标题、一个Message、三个Button。其它使用与前面介绍的一致。 ProgressDialog:可以修改的内容有一个标题、一个Message、Progress样式。Reference:
ProgressDialog pd = new ProgressDialog(context);
pd.setTitle(&Loading...&);
pd.setMessage(&Please wait.&);
pd.setCancelable(false);
pd.show();
pd.dismiss();
更多DialogFragment用法参考:
深入分析 分析目的在于了解DialogFragment视图如何动态添加View到屏幕上,跟PopupWindows一样?我们 从android.support.v4.app.DialogFragment的show方法入手。
DialogFragment.class public class DialogFragment extends Fragment
show()@DialogFragment.class
public void show(FragmentManager manager, String tag) {
mDismissed =
mShownByMe =
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag); //note1
ft.commit();
} 1、添加的Fragment是没有containerID的。onCreateView方法的参数ViewGroup container为null,表明onCreateView所创建出来的View显示到所属Activity的布局中的某个View中。既然如此,那肯定是DialogFrament通过重写父类Fragment的生命周期中的某些方法,在方法内部动态向手机屏幕上显示对话框视图,往下我们就对Fragment中的方法进行说明。对于Fragment的生命周期等感兴趣的可以参考本人另外一篇博客:
简单回顾一下Fragment的生命周期先后调用的方法有: onAttach、onCreate、onCreateView、onViewCreated、onActivityCreated、onStart、onResume、onPause 、onStop、on Destroy View、onDestory、 onDetach。
下面我们依次来分析一下DialogFrament的这些方法。
常用域以及其初始化@DialogFrament.class
public static final int STYLE_NORMAL = 0;
public static final int STYLE_NO_TITLE = 1;
public static final int STYLE_NO_FRAME = 2;
public static final int STYLE_NO_INPUT = 3;
int mStyle = STYLE_NORMAL;
int mTheme = 0;
boolean mCancelable =
boolean mShowsDialog =
int mBackStackId = -1;
//Dialog显示的关键
boolean mViewD
boolean mD
boolean mShownByMe; onAttach方法执行之前正常情况下会先执行DialogFragment的show方法,而该方法会执行如下了内容:mDismissed = mShownByMe =
onAttach()@DialogFrament.class
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!mShownByMe) { //正常情况不会跳转到这里
mDismissed =
onCreate()@DialogFrament.class
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mShowsDialog = mContainerId == 0; //note1
if (savedInstanceState != null) { //恢复之前的设置,第一次创建将不会进入到这里
mStyle = savedInstanceState.getInt(SAVED_STYLE, STYLE_NORMAL);
mTheme = savedInstanceState.getInt(SAVED_THEME, 0);
mCancelable = savedInstanceState.getBoolean(SAVED_CANCELABLE, true);
mShowsDialog = savedInstanceState.getBoolean(SAVED_SHOWS_DIALOG, mShowsDialog);
mBackStackId = savedInstanceState.getInt(SAVED_BACK_STACK_ID, -1);
} 1、 正常情况这里mShowsDialog为真,mContainerId属性来自于Fragment值为0
& & 往下就要分析onCreateView方法,但是根据博客
的分析,在onCreateView方法的第一个参数(LayoutInflater inflater)通过调用Fragment的getLayoutInflater()方法获得,因此执行顺序是先getLayoutInflater()之后再onCreateView方法。DialogFragment重写了Fragment的getLayoutInflater()方法没有重写onCreateView方法。
getLayoutInflater()@DialogFrament.class
public LayoutInflater getLayoutInflater(Bundle savedInstanceState) {
if (!mShowsDialog) { //根据前面的分析正常情况下mShowsDialog为真
return super.getLayoutInflater(savedInstanceState);
mDialog = onCreateDialog(savedInstanceState); //note1
if (mDialog != null) {
setupDialog(mDialog, mStyle); //note2
return (LayoutInflater) mDialog.getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE); //返回所属dialog的LayoutInflate对象,用于解析onCreateView中的xml布局文件
return (LayoutInflater) mHost.getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE); //返回所属context的LayoutInflate对象,用于解析onCreateView中的xml布局文件
} 1、调用onCreateDialog方法创建一个特定的Dialog对象
@NonNull &public Dialog onCreateDialog(Bundle savedInstanceState) { & & & & return new Dialog(getActivity(), getTheme()); //参数分别为当前DialogFragment所属Context、以及自身属性int mTheme = 0; } 创建了一个android.app.Dialog对象
2、调用setupDialog方法, 针对不同的style 对dialog进行相关的设置,默认style是normal,这里不进行特别处理。
public void setupDialog(Dialog dialog, int style) { & & & & switch (style) { & & & & & & case STYLE_NO_INPUT: & & & & & & & & dialog.getWindow().addFlags( & & & & & & & & & & & & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | & & & & & & & & & & & & & & & & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); & & & & & & case STYLE_NO_FRAME: & & & & & & case STYLE_NO_TITLE: & & & & & & & & dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); & & & & } &}
& & 往下分析onViewCreated,但是DialogFragment没有重写该方法,因此分析onActivityCreated方法。这里补充一下Fragment的onActivityCreated和onStart方法会在Activity的onStart方法中被先后调用。
onActivityCreated()@DialogFragment.class
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (!mShowsDialog) {
View view = getView(); //onCreateView创建出来的view
if (view != null) {
if (view.getParent() != null) {
throw new IllegalStateException(&DialogFragment can not be attached to a container view&);
mDialog.setContentView(view); //将view交给dialog显示
mDialog.setOwnerActivity(getActivity());
mDialog.setCancelable(mCancelable);
mDialog.setOnCancelListener(this);
mDialog.setOnDismissListener(this);
if (savedInstanceState != null) { //同样的初次启动不会进入到这里的代码
Bundle dialogState = savedInstanceState.getBundle(SAVED_DIALOG_STATE_TAG);
if (dialogState != null) {
mDialog.onRestoreInstanceState(dialogState);
} 这个方法的功能也就是对前面getLayout Inflater方法中创建的dialog进行设置、将onCreateView方法创建的View进行 绑定 、设置监听器等。 onActivityCreated方法执行完成后接着就是执行DialogFragment的onStart方法
onStart()@DialogFragment.class
public void onStart() {
super.onStart();
if (mDialog != null) {
mViewDestroyed =
mDialog.show(); //note1
} 1、调用dialog的show方法进行视图真正的显示 DialogFramet没有重写Fragment的onResume方法,因此对于一个Dialog的显示就到此为止。相应的DialogFragment重写的Fragment的onStop、onDestroy View、 &onDetach方法具体代码如下
onStop()@DialogFragment.class
public void onStop() {
super.onStop();
if (mDialog != null) {
mDialog.hide();
onDestroyView()@DialogFragment.class
public void onDestroyView() {
super.onDestroyView();
if (mDialog != null) {
mViewDestroyed =
mDialog.dismiss();
onDetach()@DialogFragment.class
public void onDetach() {
super.onDetach();
if (!mShownByMe && !mDismissed) {
mDismissed =
} 上面代码很简单就不具体介绍了,通过前面的分析大体得出如下结论DialogFragment,之所以继承自Fragment而不是直接使用Dialog目的在于使用FragmentManager管理其生命周期。FragmentManager只是对Dialog的生命周期进行管理,而具体的视图显示工作还是交给android.app.Dialog进行处理,如调用Dialog的show、hide、dismiss方法对对话框进行显示、隐藏、销毁
下面我们探究一下Dialog是如何显示到屏幕上的,回顾前面用到的方法,大体有如下几个: //创建Dialog mDialog = new Dialog(getActivity(), getTheme()); &//第二个参数正常情况为0
mDialog.setContentView(view);
mDialog.setOwnerActivity(getActivity());&
mDialog.setCancelable(mCancelable);&
mDialog.setOnCancelListener(this);&
mDialog.setOnDismissListener(this);
//显示、隐藏和销毁Dialog mDialog.show(); mDialog.hide(); mDialog.dismiss(); 根据这几个方法我们来分析一下Dialog的显示原理
Dialog.class (android.app.Dialog)
final Context mC
final WindowManager mWindowM
private Handler mListenersH
Dialog()@Dialog.class
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) { //通过DialogFragment创建的一般都是这种情况
final TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(R.attr.dialogTheme, outValue, true); //从context的主题中获取到dialogTheme属性
themeResId = outValue.resourceId;
mContext = new ContextThemeWrapper(context, themeResId); //利用初始化mContext带主题
mContext =
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); //负责窗口管理服务
final Window w = new PhoneWindow(mContext); //创建PhoneWindow,用于具体显示
w.setCallback(this); //dialog实现了Window.Callback接口,里面定义了如dispatchKeyEvent等处理用户点击事件的操作
w.setOnWindowDismissedCallback(this);
//处理窗口销毁时的接口
w.setWindowManager(mWindowManager, null, null);
w.setGravity(Gravity.CENTER);
mListenersHandler = new ListenersHandler(this);
} 构造器主要完成功能就是获得context的WindowManager引用;创建一个PhoneWindow,并对其进行一定初始化操作。
setContentView()@Dialog.class
public void setContentView(View view) {
mWindow.setContentView(view); //调用PhoneWindow的同名方法
setOwnerActivity() @Dialo g.c lass
private Activity mOwnerA
public final void setOwnerActivity(Activity activity) {
mOwnerActivity =
mWindow.setVolumeControlStream(mOwnerActivity.getVolumeControlStream());
setCancelable()@Dialog.class
protected boolean mCancelable =
public void setCancelable(boolean flag) {
mCancelable =
setOnCancelListener()@Dialog.class
private String mCancelAndDismissT
private Message mCancelM //用于存储一个取消Message,在Dialog销毁时将该Message交给Handler处理
public void setOnCancelListener(final OnCancelListener listener) {
if (mCancelAndDismissTaken != null) {
throw new IllegalStateException(
&OnCancelListener is already taken by &
+ mCancelAndDismissTaken + & and can not be replaced.&);
if (listener != null) {
mCancelMessage = mListenersHandler.obtainMessage(CANCEL, listener);
mCancelMessage =
setOnDismissListener()@Dialog.class
private Message mDismissM
public void setOnDismissListener(final OnDismissListener listener) {
if (mCancelAndDismissTaken != null) {
throw new IllegalStateException(
&OnDismissListener is already taken by &
+ mCancelAndDismissTaken + & and can not be replaced.&);
if (listener != null) {
mDismissMessage = mListenersHandler.obtainMessage(DISMISS, listener);
mDismissMessage =
与前面的setOnCancelListener()方法类似,也是包装成一个Message后期交给handler去处理。
show()@ Dialog.class
private boolean mShowing =
private boolean mCreated =
public void show() {
if (mShowing) { //第一次调用不会进入到这里
if (mDecor != null) {
if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
mDecor.setVisibility(View.VISIBLE);
mCanceled =
if (!mCreated) { //第一次调用会执行下面的代码
dispatchOnCreate(null); //note1
onStart(); //note2
mDecor = mWindow.getDecorView(); //从PhoneWindows中获取DecorView
if (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) { //ActionBar为null,同时当前PhoneWindow拥有标题栏
final ApplicationInfo info = mContext.getApplicationInfo();
mWindow.setDefaultIcon(info.icon);
mWindow.setDefaultLogo(info.logo);
mActionBar = new WindowDecorActionBar(this);
WindowManager.LayoutParams l = mWindow.getAttributes();
if ((l.softInputMode
& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) == 0) {
WindowManager.LayoutParams nl = new WindowManager.LayoutParams();
nl.copyFrom(l);
nl.softInputMode |=
WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
mWindowManager.addView(mDecor, l); //note3
mShowing =
sendShowMessage(); //note4
} finally {
} 1、进行一些初始化操作,但是Dialog并没有在里面进行任何操作除了将mCreatd属性设置为true
void dispatchOnCreate(Bundle savedInstanceState) { & & & & if (!mCreated) { & & & & & & onCreate(savedInstanceState); & & & & & & mCreated = & & & & } } protected void onCreate(Bundle savedInstanceState) {& }
2、该start方法对AcitonBar设置隐藏动画使能
protected void onStart() { & & & & if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(true); }
3、将得到的DecorView添加到WindowManger进行显示。 4、将showMessage发送给Handler去处理,showMessage是在setOnShowListener(OnShowListener listener)时传入的,用于监听窗口显示时的动作,与OnDismissListener和onCancelListener类似。如果没有设置该监听器那么下面的方法就不会其任何作用。 & & private void sendShowMessage() { & & & & if (mShowMessage != null) { & & & & & & Message.obtain(mShowMessage).sendToTarget(); & & & & } & & }
hide()@ Dialog.class
public void hide() {
if (mDecor != null) {
mDecor.setVisibility(View.GONE);
dismiss()@Dia log.class
public void dismiss() {
if (Looper.myLooper() == mHandler.getLooper()) {
dismissDialog();
mHandler.post(mDismissAction); //如果不是UI线程则将dismiss交给handler去处理
dismissDialog()@Dialog.class
void dismissDialog() {
if (mDecor == null || !mShowing) {
if (mWindow.isDestroyed()) {
Log.e(TAG, &Tried to dismissDialog() but the Dialog's window was already destroyed!&);
mWindowManager.removeViewImmediate(mDecor); //从WindowManager中remove DecorView
} finally {
if (mActionMode != null) {
mActionMode.finish(); .//销毁ActionBar
mWindow.closeAllPanels();
mShowing =
sendDismissMessage(); //触发dismiss监听器
} 综上我们对Dialog的分析可以知道,首先根据Context和Theme得到一个新的Context,随后根据Context得到一个WindowManager,并根据context创建一个PhoneWindow,随后通过PhoneWindow.setContentView(view)将自定义的View传给PhoneWindow。show方法中则从PhoneWindow中获得一个DecorView(DecorView是PhoneView的内部类),最后将该DecoreView添加到WindowManager中。hide方法最为简单就是调用mDecor.setVisibility(View.GONE),设置view为不可见状态。而dismiss就是类似show的逆过程,将DecorView从WindowManager中移除出去。 补充:如果以前有对Android系统底层有过分析的话可以知道这里的过程与Activity中创建View的过程类似,也是先后创建PhoneWindow和DecorWindow,最后通过WindowManager.addView方法将DecorView交给WindowManagerService进行显示。Activity的setContentView方法如下
setContentView@Activity.class public void setContentView(@LayoutRes int layoutResID) { & & & & mWindow.setContentView(layoutResID); & & & && initWindowDecorActionBar(); //对ActionBar进行一些初始化 } private Window mWindow = new PhoneWindow(this); 可以发现跟这里的流程基本都是一样的,OnCreate中创建PhoneWindow然后得到Decorview,最后在onResume方法中将Decorview交给WindowManager去处理,其实最终是交给WindowManagerService进行管理,后者负责显示视图和传递用户的事件 。
到此为止我们沿着DialogFragment-&Dialog-&PhoneWindow DecoreView WindowManager的轨迹分析了DialogFragment的显示流程。最后 如果对PhoneWindow 如何显示 感兴趣,那就需要查看
的setContentView以及getDecorView两个方法, 以及
的addView方法进行探究。这部分内容留待后面有机会再来分析。
请尊重他人劳动成果,请勿随意剽窃,转载请注明,谢谢! 转载请注明出处: http://blog.csdn.net/evan_man/article/details/
DialogFrament是一类特定的Fragment,会将视图绘制在Ac
相关阅读排行
相关内容推荐
请激活账号
为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。
您的注册邮箱:
如果您没有收到激活邮件,请注意检查垃圾箱。}

我要回帖

更多关于 actionbar 设置颜色 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信