6

I want to make an app with a login activity/layout similar to what Facebook app has. What I mean is when text field is focused soft keyboard pushes the entire view up but not squashing a logo. I have tried android:windowSoftInputMode="adjustPan/adjustResize" but it is not what I was trying to achieve.

I found this question on SO perhaps it will make things clearer, but it has no solution to the problem.

I have also tried various layouts types but it soft keyboard only pushes the focused < EditText > up. Please guide me.

UPDATE:

enter image description hereenter image description here

enter image description hereenter image description here

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="#DDDDDD">
    <RelativeLayout 
        android:height="0dp"
        android:layout_weight="1"
        android:layout_height="0dp"
        android:layout_width="fill_parent"
        android:background="#ff0000">
        <ImageView
            android:layout_centerVertical="true"
            android:layout_height="fill_parent"
            android:layout_width="fill_parent"></ImageView>
    </RelativeLayout>
    <RelativeLayout 
        android:height="0dp"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_width="fill_parent"
        android:background="#00ff00">
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#0000ff"
        android:height="0dp" >

        <Button
            android:layout_width="fill_parent"
            android:layout_height="40dp"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:text="Log in" 
            />

        <EditText
            android:layout_width="fill_parent"
            android:layout_height="40dp"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:padding="4dp"
            android:hint="password"
            android:inputType="textPassword" >
        </EditText>

        <EditText
            android:id="@+id/editText1"
            android:hint="login"
            android:padding="4dp"
            android:layout_width="fill_parent"
            android:layout_height="40dp"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true" ></EditText>
    </RelativeLayout>

</LinearLayout>

UPDATE working solution I can't paste here the entire xml file, but the structure should be enough. Based on Gabe Sechan's answer.

Layout{
   Layout top weight 1
   Layout mid weight 1
   Layout bot weight 1
}

Child layouts have set to:

android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"  // should be changed accordingly to your layout design. 

And here is a Java code for the activity(keyboard up/down):

View top, mid, bot;
    final View activityRootView = findViewById(R.id.loginLayout);
            activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(
                    new OnGlobalLayoutListener() {
                        @Override
                        public void onGlobalLayout() {
                            int heightDiff = activityRootView.getRootView()
                                    .getHeight() - activityRootView.getHeight();
                            if (heightDiff > 100) { //keyboard up
                                mid.setVisibility(View.INVISIBLE);
                                top.setLayoutParams(new TableLayout.LayoutParams(
                                        LayoutParams.MATCH_PARENT, 0, 0f));
                                bot.setLayoutParams(new TableLayout.LayoutParams(
                                        LayoutParams.MATCH_PARENT, 0, 1f));
                                
                            } else {// keyboard down
                                // v.setVisibility(View.VISIBLE);
                                mid.setVisibility(View.VISIBLE);
                                top.setLayoutParams(new TableLayout.LayoutParams(
                                        LayoutParams.MATCH_PARENT, 0, 2f));
                                bot.setLayoutParams(new TableLayout.LayoutParams(
                                        LayoutParams.MATCH_PARENT, 0, 3f));
                                
                            }
                        }
                    });
   
       

On keyboard up you need to change weights accourding to keyboard up design and on keyboard down change back to the default(layout that you've set via xml/java). I've tested the code on 2.3.x and up. And don't forget to use android:inputType="textFilter" for the login&password EditText's to remove suggestions on input and save some pixels. In your manifest for the activity android:windowSoftInputMode="adjustResize|stateHidden". stateHidden is used so that keyboard won't be up when activity loads. Hope it helps. Good luck.

Community
  • 1
  • 1
Cԃաԃ
  • 1,259
  • 1
  • 15
  • 29

2 Answers2

8

They're doing it with relative layouts, adjustResize, and android:layout_centerVertical. Basically, they have a linear layout for their main layout, with 3 equally weighted relative layouts inside of it. Each is set to 0dp height, so they take up equal thirds of the screen. The top RelativeLayout holds the logo, centered vertically. The middle holds the login fields and button, centered vertically one on top of the other. The bottom one holds the copyright text, aligned to bottom. The end result is that when the keyboard comes up, the 3 relative layouts get resized to take 1/3 of the new screen. Then their elements are centered in the new screen.

Remember you need the adjustResize window mode to get this, if you use pan it will just move up and the logo will scroll off center.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • Can you please see my update. In facebook app part that contains login fields is not resized, but top and bottom elements get resized. In my app fields get merged. Help me please. I wrote the xml based on your answer. New to android. – Cԃաԃ Apr 17 '13 at 05:41
  • 1
    In the facebook layout, since the bottom is almost completely empty, you can give it much less weight than the login field section, letting it get bigger at the expense of the others. You can play with the weights of the 3 sections to get it where you want. I'd also probably make the heights of the EditTexts and buttons wrap_content to save a few pixels. – Gabe Sechan Apr 17 '13 at 05:45
  • Thanks, playing with weight solved is what i needed. Do you know how to change the weight of a view/layout programmatically ? – Cԃաԃ Apr 17 '13 at 06:55
  • 1
    Yes- you need to set the views LayoutParams to an instance of LinearLayout.LayoutParams with the weight set. – Gabe Sechan Apr 17 '13 at 06:57
0

In Eclipse, go to File|New|Other and in the Wizard that follows, select Android Activity, then on the next page, select LoginActivity from the list of activities. This has the exact layout you're talking about, and you can use that as a framework. It uses a ScrollView to achieve the effect you're looking for.