您的位置:首页 > 移动开发 > Android开发

Android中全屏Dialog的实现

2017-04-07 13:54 405 查看
Dialog是APP开发中常用的控件,同Activity类似,拥有独立的Window窗口,但是Dialog跟Activity还是有一定区别的,最明显的就是:默认情况下Dialog不是全屏的,所以布局实现不如Activity舒服,比如顶部对齐,底部对齐、边距、宽度、高度等。如果将Dialog定义成全屏的就会省去很多问题,可以完全按照常用的布局方式来处理。网上实现方式有不少,一般情况下也都能奏效,不过可能会有不少疑虑,比如:为什么有些窗口属性(隐藏标题)必须要在setContentView之前设置才有效,相反,也有些属性(全屏)要在之后设置才有效。这里挑几个简单的实现方式,然后说下原因,由于Android的窗口管理以及View绘制是挺大的一块,这里不过多深入。

这里就说两种方式:

针对Dialog的实现方式

public class FullScrreenDialog extends Dialog {
public FullScrreenDialog(Context context) {
super(context);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
<!--关键点1-->
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_full_screen, null);
<!--关键点2-->
setContentView(view);
<!--关键点3-->
getWindow().setBackgroundDrawable(new ColorDrawable(0x00000000));
<!--关键点4-->
getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
}
}


这里牵扯到四个点,关键点1要在setContentView之前设置,主要是为了兼容一些低版本的,不让显示Title部分,关键点2就是常用的setContentView,关键点3根4就是为了全屏对话框做的修改,关键点4必须要放在setContentView的后面,因为如果放在setContentView前面,该属性会被setContentView函数冲掉无效,原因再后面说。如果你想封装一个统一的全屏Dialog,那可以吧关键点1放在构造方法中,把关键点3与4放在onStart中,其实就是主要是保证setContentView的执行顺序,
public class FullScreenDialog extends Dialog {
public FullScreenDialog(Context context) {
super(context);
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
}

@Override
protected void onStart() {
getWindow().setBackgroundDrawable(new ColorDrawable(0x00000000));
getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
}
}


针对DialogFragment的实现方式

Android比较推荐采用DialogFragment实现对话框,它完全能够实现Dialog的所有需求,并且还能复用Fragment的生命周期管理,被后台杀死后还能自动恢复。其实现全屏的原理同Dialog一样,只不过是时机的把握
public class FullScreen DialogFragment extends DialogFragment {

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_full_screen, container, false);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
<!--关键点1-->
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
super.onActivityCreated(savedInstanceState);
<!--关键点2-->
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(0x00000000));
getDialog().getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
}

}


先看下这里为什么放在onActivityCreated中处理,如果稍微跟下DialogFragment的实现源码就会发现,其setContentView的时机是在onActivityCreated,看如下代码关键点1
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (!mShowsDialog) {
return;
}
View view = getView();
if (view != null) {
if (view.getParent() != null) {
throw new IllegalStateException("DialogFragment can not be attached to a container view");
}
<!--关键点1-->
mDialog.setContentView(view);
}
...
}


当然,也完全可以参考基类Dialog的实现方式,其实关键就是把握 setContentView的调用时机。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息