Graeme
Graeme

Reputation: 25864

How to create a transparent activity WITHOUT windowIsFloating

windowIsFloating while a great one stop shop for creating Dialog styled UI's has many ---bugs--- quirks.

The one which I'm battling right now is that it assigned the width/height of the top ancestor as "wrap_content" rather than the width/height of the screen. This means the usual UI design of using "match_parents" will propogate upwards to become "wrap_content". Bad times.

So, what I would really like is to create an activity, and have a layout like so:

<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> 

Which produces a UI showing a single window (@id/singlePane) ontop of the Activity which called it.

Does anybody have the just right set of styles needed to create a transparent background Activity?

Upvotes: 21

Views: 14681

Answers (3)

headuck
headuck

Reputation: 2783

The accepted answer works fine, until I need to have an EditText inside the dialog-style window, as the soft IME keyboard would not push the "dialog" up without windowIsFloating. So I have to tackle the 'bug' head-on.

As with the case in the question, I need to have the width set to "match_parent" while the height can remain "wrap_content". Using windowIsFloating, I end up setting up a ViewTreeObserver, traverse up the view tree during layout, and force the floating window to the desired width. The approach is as follows (under onCreate() of the Activity) -

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);
        }
    }
});

This works up to Android 7 so far (even in split screen mode), but one may catch the possible cast exception for casting to WindowManager.LayoutParams in case future implementation changes, and add removeOnGlobalLayoutListener(); in an appropriate place.

Upvotes: 0

Graeme
Graeme

Reputation: 25864

Thanks to @PolamReddy who nudged me towards answer I wanted:

The theme Theme.Translucent.NoTitleBar.Fullscreen and its ancestors contains all the attributes you need to create a translucent window. In order to get everything apart from windowIsFloating I went through the ancestor stack and pulled out the entire set of attributes:

<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> 

This style must be assigned to the Activity in the AndroidManifest.xml rather than the root view of a layout.

Upvotes: 32

RajaReddy PolamReddy
RajaReddy PolamReddy

Reputation: 22493

use like this for activity in the manifest file ( theme represents the transparent of that activity.)

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

Upvotes: 8

Related Questions