InputAwarePanel for Chat and Messaging Apps

InputAwarePanel

Pretty much everyone who’ve tried to create some sort of text input page in a Windows Phone app has probably encountered the sometimes annoying way occluded TextBoxes are handled. Whenever a TextBox in focus on a device without a hardware keyboard, a software InputPane is shown so the user can input text. However, if the InputPane covers up the TextBox, the OS slides the whole page up so the TextBox is visible. The problem with this is anything at the top of the page is now unreachable because it has been slid out of view. Luckily, I’ve written a control that mimics more closely to the native OS’ way of handling occluding InputPanes and it’s now available in my toolkit QKit.

The Material

VS_IconSAMPLE SOLUTION – see it in action
VS_IconNUGET – download and use

The Problem

Let’s say we want to create a chat app. The basic layout of a chat page is a history of messages in chronological order and a TextBox that will allow the user to compose and send a new message. This, obviously, describes the exact layout as the Messaging app found in the OS. If we create this ourselves, we can have it working properly with a TextBox, a ListView, and simple TextBlock for the contact name at the top with little issues. I’ve even created custom templates for the conversation history to look more like the native Messaging app.

ChatSampleDefault

Now, in its default state, it looks and works as expected. The conversation history is a scrollable ListView while the TextBox and the TextBlock “John Doe” at the top do not move and is intended to be continuously visible. It all goes downhill when we tap on the TextBox at the bottom show the InputPane.

NormalEnsureVisibleTextInput

The first issue we can see is that the top TextBlock “John Doe” is now no longer visible. The user cannot easily check who they’re messaging unless the they close the InputPane. This is due to the sliding up of the page to ensure the TextBox is visible. Not only is any top content unreachable when the InputPane is shown, we also cannot scroll up to the oldest message in the history list for the same reason (the top message reads “Hello”).

Scrolled all the way to the top.
Scrolled all the way to the top.

The Solution

With my InputAwarePanel, whenever the InputPane is shown, the page will no longer slide up. Instead, my InputAwarePanel will resize to make room for the InputPane and essentially reduces the working visible area of the page to the region below the StatusBar and above the InputPane.

IAPEnsureVisibleTextInput

Notice how both the TextBlock at the top and the first message “Hello” is visible with my panel. The basic set up is as simple as this:

<q:InputAwarePanel>
    your content here...
</q:InputAwarePanel>

The simplest way to use this is to just put all of the page’s content inside the InputAwarePanel. This way, whenever the InputPane shows itself, the whole page acts as if it’s shrinking upwards to make room for the InputPane. Keep in mind that this no longer ensures the focused TextBox will be visible so you have to manually scroll it into view if it’s in a ScrollViewer or do other additional work. In my sample app, I have additional code in the code behind to make sure everything acts properly.

How It Works

No Animation

The InputAwarePanel has three different animation modes for flexibility. The first and easiest animation mode is None. In this mode, the InputAwarePanel simply pads the bottom of the its contents to make room for the InputPane instantly.

InputPane removed for visualize InputAwarePanel behavior
InputPane removed to visualize InputAwarePanel behavior

Dependent Animation

This animation mode is identical to how the None animation mode works except that it is done over a period of time in a similar manner as how the InputPane shows and hide. It has pretty much the same easing and duration as the animation for how the InputPane shows and hides. This animation mode is most like how the native OS handles the InputPane like in the Messaging app. Basically, the end result looks like the InputPane pushes up against the page and forces it to shrink to make room for it. The only issue with this mode is that it needs to run on the UI thread in order to achieve this effect. Because of this, the animation can be choppy in certain scenario and layout set ups. This is, in most cases, the preferred animation mode but I have another animation mode in case the performance on this isn’t ideal.

IAPDependent

Independent

Finally, this animation mode runs entirely on the compositor thread so it smoother even when the UI thread is blocked by some other process or heavy load. This animation is completely different in order to accomplish this. First, the content of the page is instantly resized to the available height that will be available after the InputPane is shown. Then, the content of the panel slides upward to make room for the InputPane. This is similar to how WP apps normally handles the InputPane but with the added resizing before the sliding. The resizing ensures all of the content is in the visible bounds still. The problem with this is because it does the resizing first instantly, any top item included in the panel will jump around before ending with the correct layout for the InputPane.

IAPIndependent

In the sample app, there’s a page where you can switch between the three animation modes to see the difference for yourself.

Advertisements

5 thoughts on “InputAwarePanel for Chat and Messaging Apps

  1. Awesome and super useful! Found one issue while reading the source code: subscribing to InputPane events in the ctor will cause memory leaks. Subscribing on Loaded and unsubscribing on Unloaded should fix it.

  2. Found the animation Silverlight uses (Microsoft.Phone.dll):
    ease = new PowerEase { EasingMode = EasingMode.EaseOut, Power = 7 };
    duration = TimeSpan.FromMilliseconds(500.0);

    Looks somewhat better to me. Just FYI.

    1. Thanks, I’ll look into incorporating this when I have a chance. Is there a way I can see this for myself? And is this the same animation curve for both showing and hiding?

      1. Yes. It’s in the SipHelper class in Microsoft.Phone.dll. To get the dll I usually run Windows Phone Application Analysis and there will be a Microsoft.Phone.ni.dll file somewhere under the ProjectFolder\PerfLogs folder.
        As far as I can see it’s the same animation for showing and hiding.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s