Как создать прозрачное действие БЕЗ всплывающего окна

#android #android-layout

#Android #android-макет

Вопрос:

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

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

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

Ответ №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:

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

Как и в случае с вопросом, мне нужно, чтобы ширина была установлена "match_parent" , а высота может оставаться "wrap_content" . Используя windowIsFloating , я в конечном итоге настраиваю a 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) amp;amp; (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(); в соответствующее место.