Android Soft Keyboard block The final solution of the input box _android

Source: Internet
Author: User

Objective

Development has been done for a long time, it is unavoidable to encounter all kinds of pits.

On the Android Development Trail, the "soft keyboard blocks the input box" is a long, drawn-out pit--come on, let's take a look.

Introductory articles

The most basic situation, as shown in the picture: there is a edittext at the bottom of the page, if you do not do any processing, then when the soft keyboard pops up, it may block the edittext.

The handling of this situation is simply that you need to set the activity in the Androidmanifest file: Android:windowsoftinputmode value Adjustpan or adjustresize, like this:

<activity
android:name= ". Mainactivity "
android:windowsoftinputmode=" Adjustpan "> ...
</activity>

In general, they can solve the problem, of course, Adjustpan and adjustresize effect slightly different.

Adjustpan is to move the entire interface upward, so that the input frame exposed, will not change the layout of the interface;

Adjustresize is to recalculate the interface size after the pop-up soft keyboard, which is equivalent to displaying content with fewer interface areas, and the input box is naturally within.

↑↑↑ok, this is just a primer, and basically all the Android engineers on Earth can handle it.

Don't worry, look down.

Plus WebView try? The Pit is coming ...

In the introductory passage above, the soft keyboard is ejected by the native EditText trigger. When H5 and hybrid are almost standard apps, we often encounter situations where the soft keyboard is triggered by a page element in the WebView.

Situation description

That's when things get complicated:

First, when the page is not full-screen mode, setting Adjustpan for the activity will fail.

Second, the page is Full-screen mode of the situation, Adjustpan and adjustresize will be ineffective.

--to explain, the Full-screen mode here is that the page is full screen, including application or activity using the fullscreen theme, the use of "state color coloring", "immersed status bar", "immersive mode" and so on--in short, Basically, the problem arises when the app itself takes over the control of the status bar.

The following table provides a simple list of specific situations.

Why does it say it's a pit? "Issue 5497"

This is not what Google expects from the table above, and ideally, of course, they all work properly-so it's a bug in the Android system itself.

Why did the article begin by saying it was a pit?

Since the bug was reported from the android1.x era (2009), it has not been repaired until now Android7.0 (2016) .../(ㄒoㄒ)/
It's not just a pit, it's an official digging hole, you can say.

"Issue 5497", details of the portal ☞issue 5497-android-webview adjustresize Windowsoftinputmode breaks when the activity is fullscreen-a Ndroid Open Source project-issue tracker-google Project Hosting

Of course, no matter who dug the pit, eventually the developers to solve.

After encountering a pit, there are two ways to go: hide, or fill.

Hide in the pit position

As indicated above, the condition of the pits is that the activity with WebView uses Full-screen mode or Adjustpan mode.

Then the hiding-hole posture is simple

If there is a webview in the activity, do not use Full-screen mode, and its Windowsoftinputmode value set to Adjustresize is good

What, is it easy?

But there are always times when it is necessary to have Full-screen mode with WebView, this time, to avoid the pit, we need a new landfills posture. Fortunately, the developer's wisdom is endless, the pit has been around for so many years, or someone found some solutions.

Androidbug5497workaround

I personally think the best solution is this: Androidbug5497workaround, just a magical androidbug5497workaround class.

See the name to know, it is specifically used to deal with the "5497" problem, the use of steps is also super simple:

Copy the Androidbug5497workaround class to the project

Add a androidbug5497workaround.assistactivity (this) to the OnCreate method of the activity that requires landfills.

After testing, basically in each Android version is available, the effect is basically set adjustresize equivalent.

Look at a contrast chart:

From the app of my plant, a full-screen mode activity page using WebView, from left to right: no soft keyboard style, soft keyboard blocking the effect of the input box, and the final effect after the use of Androidbug5497workaround.

What is the principle of it?

This cool Androidbug5497workaround class, in fact, is not very complicated, only dozens of lines of code, first posted here:

public class Androidbug5497workaround {//For more information, https://code.google.com/p/android/issues/detail?id
=5497//To use this class, the simply Invoke Assistactivity () on a activity that already has its content view set. public static void assistactivity [activity activity] {new androidbug5497workaround (activity);} private View Mchildofcon
Tent
private int usableheightprevious;
Private Framelayout.layoutparams Framelayoutparams; Private Androidbug5497workaround (activity activity) {framelayout content = (framelayout) Activity.findviewbyid ( Android.
R.id.content);
mchildofcontent = Content.getchildat (0);
Mchildofcontent.getviewtreeobserver (). Addongloballayoutlistener (New Viewtreeobserver.ongloballayoutlistener () {
public void Ongloballayout () {possiblyresizechildofcontent ();}});
Framelayoutparams = (framelayout.layoutparams) mchildofcontent.getlayoutparams (); private void Possiblyresizechildofcontent () {int usableheightnow = Computeusableheight (); if (Usableheightnow!)= usableheightprevious) {int usableheightsanskeyboard = Mchildofcontent.getrootview (). getheight (); int
Heightdifference = Usableheightsanskeyboard-usableheightnow; if (Heightdifference > (USABLEHEIGHTSANSKEYBOARD/4)) {//keyboard probably just became visible Framelayoutparams.heig
HT = usableheightsanskeyboard-heightdifference; else {//keyboard probably just became hidden framelayoutparams.height = Usableheightsanskeyboard;} mchildofcontent.re
Questlayout ();
usableheightprevious = Usableheightnow; } private int Computeusableheight () {Rect r = new Rect (); Mchildofcontent.getwindowvisibledisplayframe (R); return (R.bo Ttom-r.top);//Full Screen mode: Return R.bottom}}

The code basically does a few things:

1. Find the root view of the activity

Take a look at the entry code:

Framelayout content = (framelayout) Activity.findviewbyid (Android. r.id.content);
mchildofcontent = Content.getchildat (0);

Among them, the first line of Android. The view that r.id.content refers to is the root view of the area that developers can control on all the Android activity interfaces.

If the activity is Full-screen mode, then Android. R.id.content is the full screen area.

If the activity is a normal non full-screen mode, then Android. R.id.content is all the areas except the status bar.

In other cases, such as the activity is the window, or after 7.0 of the split-screen style, android.r.id.content is also the scope of the window or split screen half of the screens-these situations are less, for the time being not considered.

The Setcontentview view/setcontent (int layres) We often use is to put our designated view or layres into the android.r.id.content and become its child view.

So, then, the second line of Content.getchildat (0) Gets the mchildofcontent, which is actually used to get the view we put in Setcontentview.

2. Set a listener monitor view tree change

Mchildofcontent.getviewtreeobserver (). Addongloballayoutlistener ({//simplified notation
possiblyresizechildofcontent ();
});

View.getviewtreeobserver () can get a Viewtreeobserver object--an observer who listens to some of the changes that occur in the current view tree. The Addongloballayoutlistener registered here is the notification callback when the current view tree's global layout (globallayout) changes, or if the view visual state changes.

--"soft keyboard Eject", is a source that triggers this event. (soft keyboard Eject will change the globallayout)

In other words, you can now hear the "soft keyboard Eject" event.

3. After the interface changes, get "available height"

When the soft keyboard pops up, the next thing is to get the available height of the changed interface (which can be used by the developer to display the height of the content).

Look directly at the code:

private int computeusableheight () {
Rect Rect = new Rect ();
Mchildofcontent.getwindowvisibledisplayframe (rect);
Rect.top is actually the height of the status bar, if it is a full-screen theme, direct return Rect.bottom can return
(rect.bottom-rect.top);
}

View.getwindowvisibledisplayframe (Rect Rect), this line of code can get to the rect--is the interface to remove the title bar, removed by the soft keyboard block, the rest of the rectangular area-as shown in the red box in the area.

Rect area Map

You can also see:

The Rect.top value is actually the height of the title bar. (In fact, this is often used as a way to get the title bar height)

The screen height is-rect.bottom and is the height of the soft keyboard. (The method to get the soft keyboard height also appears)
At this point, there are:

Available height = Rect.bottom in full-screen mode

Non-full-screen mode, available height = Rect.bottom-rect.top

4. The final step is to reset the height

The available heights we have calculated are the height of the interface currently visible in visual effects. But the actual height of the current interface is more than a soft keyboard distance from the available height.

So the final step is to set the height of the interface to a usable height--it's done.

private void Possiblyresizechildofcontent () {
int usableheightnow = Computeusableheight ();
if (Usableheightnow!= usableheightprevious) {
int usableheightsanskeyboard = Mchildofcontent.getrootview (). GetHeight ();
int heightdifference = Usableheightsanskeyboard-usableheightnow;
if (Heightdifference > (USABLEHEIGHTSANSKEYBOARD/4)) {
//keyboard probably just
became visible Framelayoutparams.height = usableheightsanskeyboard-heightdifference;
} else {
//keyboard probably just became hidden framelayoutparams.height
= Usableheightsanskeyboard;
}
Mchildofcontent.requestlayout ();
usableheightprevious = Usableheightnow;
}

The above code adds a "Heightdifference > (USABLEHEIGHTSANSKEYBOARD/4)" judgment, which is designed to remove unnecessary distractions. Because there are many reasons to trigger ongloballayout events, not only is the soft keyboard pop-up changes, but also include a variety of child view hidden display changes, and their impact on the interface height is limited. With this judgment, only the height of the interface changes more than 1/4 of the screen height, will be reset height, basic to ensure that the code only responds to the soft keyboard pop-up.

Summarize

Summed up, is this:

Regular activity (without webview), direct use of Adjustpan or adjustresize

If you bring WebView:

A) If it is not Full-screen mode, you can use the Adjustresize

b if it is Full-screen mode, use Androidbug5497workaround for processing.

The above is a small set to introduce the Android soft keyboard block input box of the ultimate solution, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.