Как создать прозрачную активность БЕЗ windowIsFloating

windowIsFloating, в то время как отличный магазин для создания Dialog стилизованного пользовательского интерфейса имеет много --- ошибки --- quirks.

Тот, с которым я сейчас сражаюсь, заключается в том, что он назначил ширину/высоту верхнего предка как "wrap_content ", а не ширину/высоту экрана. Это означает, что обычный дизайн пользовательского интерфейса с использованием "match_parents" будет propogate вверх, чтобы стать "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> 

Создает пользовательский интерфейс, показывающий одно окно (@id/singlePane) ontop вызываемой операции.

Есть ли у кого-нибудь правильный набор стилей, необходимых для создания прозрачной фоновой активности?

Ответ 1

Благодаря @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> 

Этот стиль должен быть привязан к Activity в AndroidManifest.xml, а не к корневому представлению макета.

Ответ 2

используйте для этого действия в файле манифеста (тема представляет прозрачность этой активности.)

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

Ответ 3

Принятый ответ работает отлично, пока мне не понадобится EditText внутри диалогового окна, так как мягкая клавиатура IME не будет вызывать "диалог" без windowIsFloating. Поэтому я должен решить проблему "ошибка".

Как и в случае с вопросом, мне нужно, чтобы ширина была установлена ​​на "match_parent", а высота может оставаться "wrap_content". Используя windowIsFloating, я завершаю настройку ViewTreeObserver, перемещаю дерево просмотра во время компоновки и заставляю плавающее окно иметь нужную ширину. Подход следующий (под 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 в случае будущих изменений в реализации и добавить removeOnGlobalLayoutListener(); в подходящее место.