Android Dynamic Change Layout
Recent project requirements, dynamic change layout, in order to increase the customer experience, especially in the input box when the keypad, in order to avoid the small keyboard blocking app content needs to dynamically change the layout:
First look at the implementation of the effect chart:
is actually a software login interface, the initial is the first picture of the appearance, when the soft keyboard pop-up into the second image, because the login interface has user name, password, login button, not so the soft keyboard pop-up will cover the login button (in fact, before the implementation of the ScrollView into the inside, Listen to the soft keyboard pop-up after scrolling to the bottom of the soft keyboard hidden after scrolling to the top, is also possible.
The easiest way to do this is to add a few more redundant view, hide unwanted view according to the state of the soft keyboard, display the desired view, but it feels too bad, then it reminds me of the relativelayout layout of the previous two years ' study. The layout of the Relativelayout neutron control is relative position, just need to change the applied position rule when the soft keyboard pops up the hide.
Let's take a look at the layout file
<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http:// Schemas.android.com/tools "android:id=" @+id/root "android:layout_width=" Match_parent "android:layout_height=" Match_parent "android:padding=" 20DP "tools:context=" ${packagename}.${activityclass} "> <relativelayout Droid:id= "@+id/container" android:layout_width= "match_parent" android:layout_height= "Wrap_content" Android:lay Out_alignparenttop= "true" > <imageview android:id= "@+id/logo" android:layout_width= "150DP" an droid:layout_height= "150DP" android:layout_centerhorizontal= "true" android:scaletype= "Centercrop" Androi d:src= "@drawable/ic_launcher tools:ignore=" contentdescription "/> <textview android:id=" @+id/label "Android:layout_width=" wrap_content "android:layout_height=" wrap_content "android:layout_below=" @id/log
O "android:layout_centerhorizontal=" true " android:layout_marginleft= "10DP" android:layout_margintop= "10DP" android:text= "@string/hello_world" an Droid:textsize= "20sp"/> </RelativeLayout> <edittext android:id= "@+id/input" android:layout_width = "Match_parent" android:layout_height= "wrap_content" android:layout_below= "@id/container" Android:layout_margi
N= "16DP" android:hint= "Input sth."
Tools:ignore= "Hardcodedtext"/> </RelativeLayout>
Soft keyboard pop-up hidden with ongloballayoutlistener monitoring implementation of the activity application Android:windowsoftinputmode= "Statehidden|adjustresize", This begins when the soft keyboard is not displayed and the layout is resize when the soft keyboard pops up.
Next up is the code, all the code is here.
public class Mainactivity extends activity {private view root;//outermost layout private view logo;//logo icon private view Label
The text near the logo private int rootbottom = Integer.min_value;
@Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
Setcontentview (R.layout.activity_main);
Root = Findviewbyid (r.id.root);
Logo = Findviewbyid (R.id.logo);
Label = Findviewbyid (R.id.label); Root.getviewtreeobserver (). Addongloballayoutlistener (New Ongloballayoutlistener () {@Override public void OnG
Loballayout () {Rect r = new Rect ();
Root.getglobalvisiblerect (R); Enter the activity will be layout, the first call to Ongloballayout, first record start soft keyboard does not eject the bottom of the position if (Rootbottom = = Integer.min_value) {Rootbott
Om = r.bottom;
Return }//Adjustresize, the height of the soft keyboard will become smaller if (R.bottom < Rootbottom) {relativelayout.layoutparams LP = (
Layoutparams) Logo.getlayoutparams (); If the logo is not horizontally centered, the description is due to the next change in the size of the logo position caused by the layout, ignore, otherwise infinite loop if (Lp.getrules () [Relativelayout.center_horizontal]!= 0 {//logo display to upper left corner lp.addrule (relativelayout.center_horizontal, 0);//Cancel Horizontal Center Lp.addrul E (relativelayout.align_parent_left); Left align//zoom out logo for 1/2 int height = logo.getheight ();
Getmeasuredheight () int width = Logo.getwidth ();
Lp.width = WIDTH/2;
Lp.height = HEIGHT/2;
LOGO.SETLAYOUTPARAMS (LP);
The text under the logo relativelayout.layoutparams labelparams = (layoutparams) label.getlayoutparams (); Labelparams.addrule (relativelayout.center_horizontal, 0); Cancels horizontal center Labelparams.addrule (relativelayout.below, 0); Cancel the display to the bottom of the logo labelparams.addrule (relativelayout.right_of, R.id.logo); Display to the right of the logo labelparams.addrule (relativelayout.center_vertical); Center Label.setlayoutparams Vertically (LabelpaRams);
} else {//soft keyboard Relativelayout.layoutparams LP = (layoutparams) logo.getlayoutparams () when it is closed or initialized; If it is not centered horizontally, the soft keyboard is closed, otherwise it is initialized at the start or because the statement in the IF condition in this case modifies the layout of the control, ignoring it, otherwise the infinite loop if (Lp.getrules () [Relativelayout.center_
Horizontal] = = 0) {//Center logo lp.addrule (relativelayout.center_horizontal);
Lp.addrule (relativelayout.align_parent_left, 0);
Restore logo for the original size int height = logo.getheight ();
int width = logo.getwidth ();
Lp.width = width * 2;
Lp.height = height * 2;
LOGO.SETLAYOUTPARAMS (LP);
The text under the logo relativelayout.layoutparams labelparams = (layoutparams) label.getlayoutparams (); Labelparams.addrule (relativelayout.center_horizontal); Set Horizontal Center Labelparams.addrule (relativelayout.below, R.id.logo); The settings are shown below the logo labelparams.addrule (relativelayout.right_of, 0);
Cancel the display to the right of the logo Labelparams.addrule (relativelayout.center_vertical, 0);
Cancel Vertical Center Label.setlayoutparams (labelparams);
}
}
}
});
}
}
When the activity starts also carries on the layout, at this time uses the Rootbottom to record the initial outermost layout bottom position, then when the soft keyboard pops up, the layout is compressed, obtains the same view bottom position again, if compared to rootbottom small explanation soft keyboard pops up, If greater than or equal to Rootbottom description The soft keyboard is hidden.
All the code is on top and there are detailed comments, two points to note:
The 1.Activity will be layout when it is started, it will call Ongloballayout, and will normally be called two times, so that the second time will enter the Else statement, pay attention to the filter
2. Soft keyboard pop-up or hidden into the ongloballayout, at this time, according to the need to scale the size of the logo and change the logo and label position, these operations will cause again ongloballayout, need to filter out the Ongloballayout, Otherwise it will be infinite circulation.
You can see the filter conditions in the above code, in the Else statement as an example, the activity will enter else when the activity starts, at this time the logo is horizontally centered, will skip the else inside if statement, so that the first situation to deal with.
Since the soft keyboard to enter else, the logo has been because of the IF statement block to display in the upper left corner, so will enter the IF statement in else, to change the logo to the horizontal center, because the size and location of the modified logo, will lead to enter Ongloballayout again, Still enter else, but at this time already set the logo to the horizontal center, will not enter else in the IF statement, so through a conditional judgment on the above mentioned two points of attention.
About Addrule
The rules applied by each child control in Relativelayout are saved by an array, as follows:
public static final int TRUE =-1;
public void addrule (int verb) {
Mrules[verb] = TRUE;
Minitialrules[verb] = TRUE;
Mruleschanged = true;
}
public void addrule (int verb, int anchor) {
Mrules[verb] = anchor;
Minitialrules[verb] = anchor;
Mruleschanged = true;
}
With the index of a rule as subscript, the value is the anchor of the rule, and if it is relative to another child control, the value is the ID of the other child control, and if it is relative to the parent control, the value is ' TRUE ', that is, 1, and if a rule value is not applied to 0, you can see that the Removerule is to change the value of the corresponding position to 0:
public void removerule (int verb) {
Mrules[verb] = 0;
Minitialrules[verb] = 0;
Mruleschanged = true;
}
Removerule is a method of API addition, in order to be able to use it before API 17, you can use its equivalence method, as in the example above, to use addrule (verb, 0).
Thank you for reading, I hope to help you, thank you for your support for this site!