Android Dynamically Change layout

Source: Internet
Author: User

To meet this demand, first look at the picture:

In fact, is a software login interface, the initial is the first figure, when the soft keyboard pop-up into the second figure, because the login interface has a 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 inside, Listen to the soft keyboard popup after scrolling to the bottom, soft keyboard hidden after scrolling to the top, is also possible).

The simplest way is to add a few redundant view, hide the unwanted view according to the state of the soft keyboard, display the desired view, but this feeling is too bad, and then think of the previous two years of research relativelayout layout, Relativelayout the layout of the neutron control is relative, just need to change the location rules of the app when the soft keyboard pops up hidden.

Let's take a look at the layout file

<Relativelayoutxmlns: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}" >    <RelativelayoutAndroid:id= "@+id/container"Android:layout_width= "Match_parent"Android:layout_height= "Wrap_content"Android:layout_alignparenttop= "true" >        <ImageViewAndroid:id= "@+id/logo"Android:layout_width= "150DP"Android:layout_height= "150DP"Android:layout_centerhorizontal= "true"Android:scaletype= "Centercrop"android:src= "@drawable/ic_launcher"Tools:ignore= "ContentDescription" />        <TextViewAndroid:id= "@+id/label"Android:layout_width= "Wrap_content"Android:layout_height= "Wrap_content"Android:layout_below= "@id/logo"Android:layout_centerhorizontal= "true"Android:layout_marginleft= "10DP"Android:layout_margintop= "10DP"Android:text= "@string/hello_world"android:textsize= "20SP" />    </Relativelayout>    <EditTextAndroid:id= "@+id/input"Android:layout_width= "Match_parent"Android:layout_height= "Wrap_content"Android:layout_below= "@id/container"Android:layout_margin= "16DP"Android:hint= "Input sth."Tools:ignore= "Hardcodedtext" /></Relativelayout>

Soft keyboard pop-up hidden with ongloballayoutlistener monitoring implementation, the activity application android:windowsoftinputmode= "Statehidden|adjustresize", This starts when the soft keyboard is not displayed and the layout is resize when the soft keyboard pops up.

And then there's the code, and all the code is here.

 Public classMainactivityextendsActivity {PrivateView Root;//Outermost Layout    PrivateView logo;//logo icon    PrivateView label;//text near the logo    Private intRootbottom =Integer.min_value; @Overrideprotected voidonCreate (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 (NewOngloballayoutlistener () {@Override Public voidongloballayout () {Rect R=NewRect ();                Root.getglobalvisiblerect (R); //Enter activity will layout, first call Ongloballayout, first record start soft keyboard does not eject when the bottom of the position                if(Rootbottom = =integer.min_value) {Rootbottom=R.bottom; return; }                //adjustresize, when the soft keyboard pops up, the height becomes smaller.                if(R.bottom <Rootbottom) {Relativelayout.layoutparams LP=(Layoutparams) logo.getlayoutparams (); //if the logo is not horizontally centered, it is because the next change in the logo size position caused by the layout again, ignore, otherwise infinite loop                    if(Lp.getrules () [relativelayout.center_horizontal]! = 0) {                        //logo display to upper left cornerLp.addrule (relativelayout.center_horizontal, 0);//Cancel Horizontal CenteringLp.addrule (Relativelayout.align_parent_left);//Align Left//reduce logo as a                        intHeight = logo.getheight ();//getmeasuredheight ()                        intwidth =logo.getwidth (); Lp.width= WIDTH/2; Lp.height= HEIGHT/2;                        LOGO.SETLAYOUTPARAMS (LP); //the text under the logoRelativelayout.layoutparams Labelparams =(Layoutparams) label.getlayoutparams (); Labelparams.addrule (Relativelayout.center_horizontal,0);//Cancel Horizontal CenteringLabelparams.addrule (relativelayout.below, 0);//Cancel the display to the bottom of the logoLabelparams.addrule (relativelayout.right_of, R.id.logo);//Show to the right of the logoLabelparams.addrule (relativelayout.center_vertical);//Center VerticallyLabel.setlayoutparams (Labelparams); }                } Else{//when the soft keyboard is closed or initializedRelativelayout.layoutparams LP =(Layoutparams) logo.getlayoutparams (); //If there is no horizontal center, the description is the soft keyboard is closed, otherwise it is the beginning of the initialization or because the statement in the IF condition in the control caused the layout again, ignore, otherwise infinite loop                    if(Lp.getrules () [relativelayout.center_horizontal] = = 0) {                        //Center LogoLp.addrule (relativelayout.center_horizontal); Lp.addrule (Relativelayout.align_parent_left,0); //Restore logo to original size                        intHeight =logo.getheight (); intwidth =logo.getwidth (); Lp.width= width * 2; Lp.height= Height * 2;                        LOGO.SETLAYOUTPARAMS (LP); //the text under the logoRelativelayout.layoutparams Labelparams =(Layoutparams) label.getlayoutparams (); Labelparams.addrule (relativelayout.center_horizontal); //Set Horizontal CenterLabelparams.addrule (Relativelayout.below, R.id.logo);//settings are displayed below the logoLabelparams.addrule (relativelayout.right_of, 0);//Cancel display to the right of logoLabelparams.addrule (relativelayout.center_vertical, 0);//Cancel Vertical CenterLabel.setlayoutparams (Labelparams);    }                }            }        }); }}

When the activity is started, it will also be layout, when the initial outermost layout is recorded at the bottom of the position, and then when the soft keyboard pops up, the layout is compressed, again get the same view at the bottom of the position, if the rootbottom than Rootbottom Small description soft keyboard pops up, if greater than or equal to rootbottom description soft keyboard hidden.

All the code is on the top, there are detailed comments, there are two points to note:

    1. When the activity is started, the layout will be called Ongloballayout, and will generally call two times, so the second time will enter the Else statement, pay attention to filter
    2. When the soft keyboard pops up or hides into the ongloballayout, the size of the logo can be scaled as needed, and the location of the logo and label is changed, and these actions will cause the ongloballayout to be re- Ongloballayout filter out, or the infinite cycle.

You can see the filter in the above code, in the Else statement as an example, when the activity starts will go to else, when the logo is horizontally centered state, will skip the else inside if statement, so that the first case is disposed of.

When the soft keyboard is put into the else, the logo has been because the IF statement block to display in the upper left corner, so will go into the else if statement, re-change the logo to the horizontal center, due to change the size and position of the logo, will lead to re-entry ongloballayout , still go to else, but at this point the logo has been set to the horizontal center, will not go into the else if statement, so through a condition to judge the above mentioned two points of attention.

About Addrule

The rules that are applied to each child control in Relativelayout are saved by an array, as follows:

 Public Static Final intTRUE =-1; Public voidAddRule (intverb) {Mrules[verb]=TRUE; Minitialrules[verb]=TRUE; Mruleschanged=true;} Public voidAddRule (intVerbintanchor) {Mrules[verb]=anchor; Minitialrules[verb]=anchor; Mruleschanged=true;}

The index of a rule is subscript, the value is the anchor of the rule, if it is relative to another child control, the value is the ID of another child control, if it is relative to the parent control, the value is ' TRUE ', that is-1, if a rule value is not applied is 0, you can see that Removerule is to change the value of the corresponding position to 0:

 Public void removerule (int  verb) {    = 0;     = 0;     true ; }

The

removerule is the API to add a method, in order to be used before the API , you can use its equivalent method, As in the example above, use addRule (verb, 0) .

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.