如何创建一个不使用windowIsFloating属性的透明Activity

21

windowIsFloating虽然是一种非常方便的创建Dialog样式UI的工具,但它有许多奇怪的问题。

我正在遭遇的一个问题是,它将顶级祖先的宽度/高度分配为"wrap_content"而不是屏幕的宽度/高度。这意味着通常使用"match_parent"进行UI设计的方式会向上传播成为"wrap_content"。真是糟糕的时刻。

所以,我真正想要的是创建一个活动,并拥有如下布局:

<LinearLayout   android:layout_height="wrap_content"
                android:layout_width="match_parent"
                android:orientation="vertical"
                android:id="@+id/containerPageConatiner"
                android:background="@drawable/windowBackground">
    <View           android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:layout_weight="1"/>
    <FrameLayout    android:id="@+id/singlePane"
                    android:layout_height="wrap_content"
                    android:layout_width="match_parent"
                    android:layout_gravity="center_horizontal|center_vertical"
                    android:padding="10dp"/>    
    <View           android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:layout_weight="1"/>                         
</LinearLayout> 

它会生成一个UI,显示在调用它的Activity上方的单个窗口(@id/singlePane)。

有人拥有创建透明背景Activity所需的完美样式集吗?

3个回答

32

感谢@PolamReddy对我提供的帮助,他引导我找到了我需要的答案:

主题Theme.Translucent.NoTitleBar.Fullscreen及其祖先包含了创建半透明窗口所需的所有属性。为了获得除windowIsFloating之外的所有属性,我遍历了祖先堆栈并提取出整套属性:

<style name="Theme.CustomTheme.TransparentActivity">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:colorBackgroundCacheHint">@null</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowAnimationStyle">@android:style/Animation</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowFullscreen">true</item>
</style> 

必须将此样式分配给 AndroidManifest.xml中的Activity,而不是布局的根视图。


8

在清单文件中使用如下方式来表示活动(主题代表该活动的透明度):

<activity android:name=".Settings"      
          android:theme="@android:style/Theme.Translucent.NoTitleBar"/>

0
接受的答案很好用,但当我需要在对话框样式窗口中放置EditText时,软键盘不会推动“对话框”上去,除非使用windowIsFloating。所以我必须直面这个“错误”。
与问题中的情况一样,我需要将宽度设置为“match_parent”,而高度可以保持为“wrap_content”。使用windowIsFloating,我最终设置了一个ViewTreeObserver,在布局期间遍历视图树,并强制浮动窗口达到所需的宽度。方法如下(在Activity的onCreate()下)-
setContentView(contentView);

// set up the ViewTreeObserver
ViewTreeObserver vto = contentView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    int displayWidth = -1;
    DisplayMetrics metrics = null;
    View containerView = null;

    @Override
    public void onGlobalLayout() {            
        if (containerView == null) {
            // traverse up the view tree
            ViewParent v = contentView.getParent();
            containerView = contentView;
            while ((v != null) && (v instanceof View)) {
                containerView = (View) v;
                v = v.getParent();
            }
        }
        if (metrics == null) {
            metrics = new DisplayMetrics();
        }
        Display display = getWindowManager().getDefaultDisplay();
        display.getMetrics(metrics);
        if (displayWidth != metrics.widthPixels) {
            displayWidth = metrics.widthPixels;
            WindowManager.LayoutParams params = 
                    (WindowManager.LayoutParams) containerView.getLayoutParams();
            // set the width to the available width to emulate match_parent
            params.width = displayWidth;
            // windowIsFloating may also dim the background
            // do this if dimming is not desired
            params.dimAmount = 0f;
            containerView.setLayoutParams(params);
            getWindowManager().updateViewLayout(containerView, params);
        }
    }
});

目前为止,这个方法适用于 Android 7(甚至在分屏模式下也能使用)。但是,如果未来实现发生变化,则可能出现将 WindowManager.LayoutParams 强制转换时出现 ClassCastException 的情况。此时需要在适当的位置添加 removeOnGlobalLayoutListener(); 方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接