Solution to the problem of covering input box when the Android input method pops up _android

Source: Internet
Author: User

When an activity contains an input box, we click on the input box, will pop-up input interface, the entire interface change effect and manifest in the corresponding settings of the Android:windowsoftinputmode property, the general can set the value below,

<activity android:windowsoftinputmode=[
"stateunspecified",
"stateunchanged", 
"Statehidden",
"Statealwayshidden", 
"statevisible",
"statealwaysvisible", 
"adjustunspecified",
" Adjustresize "," 
Adjustpan "] ... >

Specific how to set up to view the official document. Today, the main solution when the input method is ejected will overwrite the problem of the input box.

What will be covered?

When an activity in Android is set up with Full-screen properties Theme.Light.NotittleBar.Fullscreen or set up an activity corresponding to the theme of Android: Windowtranslucentstatus property, set the way: <item name= "Android:windowtranslucentstatus" >TRUE</ITEM>, This is if the corresponding page contains an input box, will result in clicking the input box when the soft keyboard pops up after the keyboard overwrites the input box, resulting in the input box invisible.

Why?

This is actually because in Full-screen, the Adjustresize property has been invalidated, the problem is a system bug, reference link. Adjustresize not effective, there is no other way to solve it? At this time we can set the Adjust property for the Adjustpan property, this property will not be invalidated, but because the Adjustpan will be the overall translation of the page, to leave the input method space, there will be a jitter effect, the experience is very poor, where there is no experience of better methods na?

Solution:

If you are using Framelayout with the layout, you can make a custom framelayout and set the Android:fitssystemwindows property of Framelayout to True. The XML settings are as follows

<com.sample.ui.widget.insetframelayout xmlns:android= "Http://schemas.android.com/apk/res/android"
          Android:layout_width= "Match_parent"
          android:layout_height= "match_parent"
          android:fitssystemwindows= " True ">

We customize the framelayout for the Insetframelayout,insetframelayout code as follows:

Public final class Insetframelayout extends Framelayout {private int[] minsets = new Int[4];
  Public Insetframelayout {Super (context);
  Public Insetframelayout (context, AttributeSet attrs) {Super (context, attrs);
  Public Insetframelayout (context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle);
  Public final int[] Getinsets () {return minsets; } @Override Protected Final Boolean fitsystemwindows (Rect insets) {if Build.VERSION.SDK_INT >= build.version _codes. KitKat) {//intentionally does not modify the bottom inset.

      For some reason,//if the bottom inset is modified, window resizing stops.
      Minsets[0] = Insets.left;
      MINSETS[1] = insets.top;

      MINSETS[2] = insets.right;
      Insets.left = 0;
      insets.top = 0;
    insets.right = 0;
  Return Super.fitsystemwindows (insets); @Override Public Final Windowinsets OnapplywindoWinsets (windowinsets insets) {if (Build.VERSION.SDK_INT >= build.version_codes.
      Kitkat_watch) {Minsets[0] = Insets.getsystemwindowinsetleft ();
      MINSETS[1] = Insets.getsystemwindowinsettop ();
      MINSETS[2] = Insets.getsystemwindowinsetright (); Return Super.onapplywindowinsets (insets.replacesystemwindowinsets (0, 0, 0, Insets.getsystemwindowinsetbottom ()))
    ;
    else {return insets;

 }
  }

}

Official solution:

The authorities actually found the problem, so the android.support.design.internal also rewrote the framelayout to solve the problem, but the class was marked with hide.

* * Copyright (C) 2015 the Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "Licen
 Se ");
 * You could not use this file, except in compliance with the License. * Obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * unless required by APPL Icable or agreed to in writing, software * Distributed under the License was distributed on ' as is ' basis, * witho
 UT warranties or CONDITIONS of any KIND, either express OR implied.
 * The License for the specific language governing permissions and * limitations under the License.

* * Package android.support.design.internal;
Import Android.content.Context;
Import Android.content.res.TypedArray;
Import Android.graphics.Canvas;
Import Android.graphics.Rect;
Import android.graphics.drawable.Drawable;
Import Android.support.annotation.NonNull;
Import ANDROID.SUPPORT.DESIGN.R;
Import Android.support.v4.view.ViewCompat; Import Android.support.v4.view.WindowInsetsCOmpat;
Import Android.util.AttributeSet;
Import Android.view.View;

Import Android.widget.FrameLayout;

  /** * @hide * * * public class Scriminsetsframelayout extends Framelayout {private drawable minsetforeground;

  Private Rect minsets;

  Private Rect Mtemprect = new Rect ();
  Public Scriminsetsframelayout {This (context, NULL);
  Public Scriminsetsframelayout (context, AttributeSet attrs) {This (context, attrs, 0); Scriminsetsframelayout (context, AttributeSet attrs, int defstyleattr) {Super (context, Attrs, DefS

    TYLEATTR);
        Final TypedArray a = Context.obtainstyledattributes (Attrs, R.styleable.scriminsetsframelayout, Defstyleattr,
    R.style.widget_design_scriminsetsframelayout);
    Minsetforeground = a.getdrawable (R.styleable.scriminsetsframelayout_insetforeground);
    A.recycle (); Setwillnotdraw (TRUE); No need to draw until the insets are adjusted Viewcompat.setonapplywindowinsetslisteNER (This, new Android.support.v4.view.OnApplyWindowInsetsListener () {@Override public windowi
              Nsetscompat Onapplywindowinsets (View V, Windowinsetscompat insets) {if (null = = Minsets) {
            Minsets = new Rect ();
                } minsets.set (Insets.getsystemwindowinsetleft (), Insets.getsystemwindowinsettop (),
            Insets.getsystemwindowinsetright (), Insets.getsystemwindowinsetbottom ());
            Setwillnotdraw (Minsets.isempty () | | | | minsetforeground = NULL);
            Viewcompat.postinvalidateonanimation (Scriminsetsframelayout.this);
          return Insets.consumesystemwindowinsets ();
  }
        });

    @Override public void Draw (@NonNull Canvas Canvas) {Super.draw (Canvas);
    int width = getwidth ();
    int height = getheight ();
      if (minsets!= null && minsetforeground!= null) {int sc = canvas.save (); Canvas.translate (gETSCROLLX (), getscrolly ());
      Top Mtemprect.set (0, 0, width, minsets.top);
      Minsetforeground.setbounds (Mtemprect);

      Minsetforeground.draw (canvas);
      Bottom mtemprect.set (0, Height-minsets.bottom, width, height);
      Minsetforeground.setbounds (Mtemprect);

      Minsetforeground.draw (canvas);
      Left Mtemprect.set (0, Minsets.top, Minsets.left, Height-minsets.bottom);
      Minsetforeground.setbounds (Mtemprect);

      Minsetforeground.draw (canvas);
      Right Mtemprect.set (Width-minsets.right, minsets.top, Width, height-minsets.bottom);
      Minsetforeground.setbounds (Mtemprect);

      Minsetforeground.draw (canvas);
    Canvas.restoretocount (SC);
    }} @Override protected void Onattachedtowindow () {Super.onattachedtowindow ();
    if (minsetforeground!= null) {minsetforeground.setcallback (this);
}} @Override protected void Ondetachedfromwindow () {Super.ondetachedfromwindow ();    if (minsetforeground!= null) {minsetforeground.setcallback (null);

 }
  }

}

Any of these methods can be used to solve the problem of the input box after the Input method pops up.

Other questions?

We found a user feedback in our use, saying that as soon as we entered the page where we used the layout we would crash, we looked at the crash log and found that some of the phones were using the same Android system, and the version was 19,android4.4.x, a rewritten system, The code loading method for the system was rewritten.

Why would it crash?

Our code uses the Windowinsets, the class is provided by API 20, so 19 of the system does not actually have the code, but the system in the inflate of XML parsing the class, resulting in ClassNotFound.

A new Solution!

The new solution still takes the same approach, but it will write a different layout for different versions, with API 20 above and below 20 providing a separate layout, which is implemented using the System qualifier, and then more than 20 of the original is the same way, 20 to remove the onapplywindowinsets replication, so that different versions load different code on OK.

 @Override public
  Final windowinsets onapplywindowinsets (windowinsets insets) {
    if Build.VERSION.SDK_INT > = Build.version_codes. Kitkat_watch) {
      minsets[0] = Insets.getsystemwindowinsetleft ();
      MINSETS[1] = Insets.getsystemwindowinsettop ();
      MINSETS[2] = Insets.getsystemwindowinsetright ();
      Return Super.onapplywindowinsets (insets.replacesystemwindowinsets (0, 0, 0,
          Insets.getsystemwindowinsetbottom) ( )));
    } else {return
      insets;
    }
  }

Summing up to this whole solution has been completed, such as the updated solution hope you share.

Related Article

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.