[Android Software Development] klinkdawg24:
This is a project that I whipped together to show developers how to implement a floating window type popup for their apps. An example usage would be quick reply to a sms message, email, or any other times quick reply would come in handy. It isn't limited to just that though, using this method, you will be able to completely recreate any activity in windowed form with very little code edits.

​

My brother an I have used this to create a quick reply for our app, Sliding Messaging Pro. The idea is basically the exact same as Halo, with almost the exact same implementation. We do it by extending the MainActivity in a pop up class, then using an overrode setUpWindow() function to set up your MainActivity in the window.

The full source is availible on my GitHub, found here: Floating Window GitHub

Play Store Link: Floating Window Demo

So now to the actual steps to creating your own "floating window popup" out of your apps MainActivity:

1.) First, we should add the styles that we are going to use to the styles.xml sheet.

These are the styles for the animation, of course you can define your own animation if you choose, these will bring the window up from the bottom of the screen and the close it to the bottom of the screen.

<style name="PopupAnimation" parent="@android:style/Animation">
<item name="android:windowEnterAnimation">@anim/activity_slide_up</item>
<item name="android:windowExitAnimation">@anim/activity_slide_down</item>
</style>

Now, this style is for the actual popup dialog box. You can play with the different values here all you want. We end up overriding some of these when we set up the window anyways, such as the dimming.

<style name="Theme.FloatingWindow.Popup" parent="@android:style/Theme.Holo.Light" >

<item name="android:windowIsFloating">false</item>
<item name="android:windowSoftInputMode">stateUnchanged</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowActionModeOverlay">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowAnimationStyle">@style/PopupAnimation</item>
<item name="android:windowCloseOnTouchOutside">true</item>
<item name="android:backgroundDimEnabled">false</item>

</style>

2.) Now that your styles are set up, lets go ahead and add the new Popup activity to the manifest. You can see that we used the Theme.FloatingWindow.Popup style that we just defined in the last step. You will also have to add

xmlns:tools="http://schemas.android.com/tools"

to the xmlns declarations at the top of the manifest.

<activity
android:name="PopupMainActivity"
android:label="@string/app_name"
android:theme="@style/Theme.FloatingWindow.Popup"
android:configChanges="orientation|screenSize"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden"
android:clearTaskOnLaunch="true"
android:exported="true"
tools:ignore="ExportedActivity" />

3.) One more thing that we have to put in before you have resolved all the errors here, the animations. Just copy and paste these two animations in separate files under the res/anim folder. Name one activity_slide_down.xml and the other activity_slide_up.xml

activity_slide_down.xml

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android" >

<translate android:fromXDelta="0%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="100%"
android:duration="300"/>

</set>

activity_slide_up.xml

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android" >

<translate android:fromXDelta="0%" android:toXDelta="0%"
android:fromYDelta="100%" android:toYDelta="0%"
android:duration="300"/>

</set>

4.) Now that everything should be set up, we will make the actual popup activity! You can view my full code for this from the GitHub link, but basically, we are going to make a PopupMainActivity.java class and extend the MainActivity class. If you understand inheritance at all with java, you will know what this is doing. It is going to allow this PopupMainActivity class, when started, to override methods from the MainActivity to produce different outcomes.

The method that actually makes the windowed pop up I have named setUpWindow(). This means that whenever this activity is called instead of the main activity, it will use this method instead of the main activities setUpWindow() method. This is very convieniet since we don't want to do any extra work than we need to in this class. So here is the code for that class:

/**
* This method overrides the MainActivity method to set up the actual window for the popup.
* This is really the only method needed to turn the app into popup form. Any other methods would change the behavior of the UI.
* Call this method at the beginning of the main activity.
* You can't call setContentView(...) before calling the window service because it will throw an error every time.
*/
@Override
public void setUpWindow() {

// Creates the layout for the window and the look of it
requestWindowFeature(Window.FEATURE_ACTION_BAR);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND,
WindowManager.LayoutParams.FLAG_DIM_BEHIND);

// Params for the window.
// You can easily set the alpha and the dim behind the window from here
WindowManager.LayoutParams params = getWindow().getAttributes();
params.alpha = 1.0f; // lower than one makes it more transparent
params.dimAmount = 0f; // set it higher if you want to dim behind the window
getWindow().setAttributes(params);

// Gets the display size so that you can set the window to a percent of that
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

// You could also easily used an integer value from the shared preferences to set the percent
if (height > width) {
getWindow().setLayout((int) (width * .9), (int) (height * .7));
} else {
getWindow().setLayout((int) (width * .7), (int) (height * .8));
}
}

You can see what it does from the comments, but basically, it just initializes your main activity in a windowed for, exactly what we are trying to do!

5.) Now to actually have this method override something in the MainActivity, you must add the same method there. In my example, The method is just blank and has no implementation because i don't want it to do anything extra for the full app. So add this activity and the error that "your method doesn't override anything in the super class" will go away. Then you actually have to call this method from your MainActivity's onCreate() method so that it will set up the windowed app when it is suppose to.

/**
* Called when the activity is first created to set up all of the features.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

context = this;

// If the user is in the PopupMainActivity function, the setUpWindow function would be called from that class
// otherwise it would call the function from this class that has no implementation.
setUpWindow();

// Make sure to set your content view AFTER you have set up the window or it will crash.
setContentView(R.layout.main);

// Again, this will call either the function from this class or the PopupMainActivity one,
// depending on where the user is
setUpButton();
}

As you can see from the code, I called this method before i set the content view for the activity. This is very important, otherwise you will get a runtime exception and the app will crash every time.

After you are done with that, you have successfully set up a program that will change from a windowed state to a full app state depending on which class is called. For example, if you set up an intent to open the floating window app, it would look something like this:

Intent window = new Intent(context, com.klinker.android.floating_window.PopupMainActivity.class);
window.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(window);

You are still able to call the MainActivity class like you normally would then. with an intent like this:

Intent fullApp = new Intent(context, MainActivity.class);
fullApp.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(fullApp);

That is just about it, obviously my solution and demo are very simple implementations of what it can do. You can see from the demo app that I simply go back and forth between the activities with a button, then i have an edittext at the bottom to demonstrate how the window resizes.

You can literally do anything with this though. It will work with any layouts you have set up and is a very cool way for your users to experience your app in a different light. If you want to change how something works in the popup part of the app, all you have to do is function that portion of code out, then override that method from the popup activity, so the possibilities are endless with what can be done here.

Credit for this goes to the Paranoid Android team of course for inspiring the idea, then Jacob Klinker (klinkdawg) and myself (Luke Klinker) for the implementation without framework tweaks or custom roms. This should work for any users, no matter the phone, android version, or custom rom.

I honestly have no clue if it will work on anything below 4.0, but if you test and find out, sound off in the comments!

Thanks and enjoy! I hope to see lots of dynamic and awesome popups in the future because it really is just that simple, it won't take you more than a half hour to get this working! :)