1. 程式人生 > >Android輸入法彈出時把佈局頂上去和登入按鈕頂上去的解決方法

Android輸入法彈出時把佈局頂上去和登入按鈕頂上去的解決方法

背景:在寫登入介面時,老闆就覺得在輸入密碼的時候談出來的輸入法軟鍵盤把登入按鈕遮擋住了(入下圖所示,不爽),連輸入框都被擋了一半,於是不滿意了,要叫我改,於是我看QQ的登入效果,我就去研究了一下,彈出輸入法整個佈局上來了,終於讓老闆滿意了。

(如上圖這樣,老闆不滿意的,呵呵)

1,咱們就解決問題吧。

     我看了很多部落格和問答,很多人都說直接在在AndroidManifest.xml中給這個Activity設定 <activity android:windowSoftInputMode="stateVisible|adjustPan" ...>這樣就好使了,這個是否在逗,整個佈局向上移動並不明顯,反正我的是不好使,不知道那些博主是怎麼弄好使的。不過,看評論,也有很多人說不好使。那就做一個大家都好使的程式碼出來。先看效果。


    哈哈,大家有沒有看到,連登入按鈕都一起跑上去了,應該是頂上去的。老闆再也不用擔心登入按鈕被覆蓋掉了。

    那咱們就上程式碼啦:程式碼不多,全在佈局上,就可以解決。

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:fillViewport="true"
    android:fadeScrollbars="true">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="top|center_horizontal"  
            android:orientation="vertical"
            android:background="@color/red2"
            android:visibility="visible">
            <ImageView                   <!--這個其實是我放佈局中間的控制元件,我隨便寫的,放任何控制元件都可以-->
                android:layout_width="200dp"
                android:layout_height="160dp"
                />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:alwaysDrawnWithCache="true"
            android:gravity="center|center_horizontal"
            android:orientation="vertical"
            android:visibility="visible"
            android:background="@color/abc_search_url_text_normal">
            <EditText
                android:background="@color/white"
                android:layout_width="200dp"
                android:layout_height="60dp"
                />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:background="@color/cornsilk"
            android:gravity="top|center_horizontal"
            android:orientation="vertical"
            android:visibility="visible">
            <Button
                android:layout_marginTop="20dp"
                android:gravity="center"
                android:text="登入"
                android:layout_width="200dp"
                android:layout_height="50dp" />
        </LinearLayout>
    </LinearLayout>
</ScrollView>
  對上面就是所有視線程式碼了,外面一個scrollview,包含一個LinearLayout,在中間包含了三個LinearLayout,當然了包含三個什麼容器控制元件都行,但是一定要用權重(layout_weight)來約束,這是重點,我只說了一遍,還有就是LinearLayout內部的佈局儘量用wrap_content,即時要固定高度也要適當,調節調節就好了。

使用的時候很簡單,就只有上面一段佈局,然而根本用不著神馬AndroidManifest.xml中給這個Activity設定

<activity android:name=".view.activity.multisend.MultiChatActivity"
            android:windowSoftInputMode="stateVisible|adjustResize"/>

對於這段程式碼,是可以將底部如果有輸入框(最好用FrameLayout包裹),可以向上移動的,類似於QQ輸入框。可以不用ScrollView而且輸入框向上滾動時,整個佈局不會向上滾動。
2,最後再提供一個思路,這個思路來自於“卷皮”,卷皮的登入效果,他的設計思路是,在點選EditText輸入框的時候,我第一個猜測是:得到了EditText輸入焦點,或者是:猜測是監聽到鍵盤彈出的焦點之後,卷皮頂上那個背景就把它慢慢變小隱藏起來,導致下面的兩個輸入框滾動到頂部去了,就方便使用者輸入了。這個思路也很好的解決使用者直接可以輸入的問題。

3,目前很多專案要解決這個問題的方法就是如上面2解決方案所示的,logo逐漸縮小,然後scroll會滾動上去。

csdn這個編輯器越來越爛了,,圖片都搞不上來了

佈局看看:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/root"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/white"
                android:clipToPadding="true"
                android:fitsSystemWindows="true"
                android:orientation="vertical">

    <ImageView
        android:id="@+id/logo"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center"
        android:layout_marginTop="80dp"
        android:background="@null"
        android:scaleType="centerCrop"
        android:src="@mipmap/ic_launcher"/>

    <ScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp"
        android:fillViewport="true"
        android:scrollbarThumbVertical="@android:color/transparent"
        android:scrollbars="vertical">

        <LinearLayout
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="55dp"
                android:layout_marginTop="200dp"
                android:gravity="center_vertical"
                android:orientation="horizontal"
                android:paddingLeft="13dp">

                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="15dp"
                    android:src="@drawable/ic_mobile_flag"/>

                <EditText
                    android:id="@+id/et_mobile"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:background="@null"
                    android:hint="請輸入使用者名稱"
                    android:inputType="textVisiblePassword"
                    android:maxLength="11"
                    android:singleLine="true"
                    android:text=""
                    android:textColor="@color/_9"
                    android:textColorHint="@color/_9"
                    android:textSize="14dp"/>

                <ImageView
                    android:id="@+id/iv_clean_phone"
                    android:layout_width="40dp"
                    android:layout_height="fill_parent"
                    android:scaleType="centerInside"
                    android:src="@drawable/ic_clear"
                    android:visibility="gone"/>
            </LinearLayout>

            <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:background="@color/e"/>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="55dp"
                android:gravity="center_vertical"
                android:orientation="horizontal"
                android:paddingLeft="13dp">

                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="15dp"
                    android:src="@drawable/ic_password_flag"/>

                <EditText
                    android:id="@+id/et_password"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:background="@null"
                    android:hint="請輸入密碼"
                    android:inputType="textPassword"
                    android:maxLength="30"
                    android:singleLine="true"
                    android:text=""
                    android:textColor="@color/_9"
                    android:textColorHint="@color/_9"
                    android:textSize="14dp"/>

                <ImageView
                    android:id="@+id/clean_password"
                    android:layout_width="40dp"
                    android:layout_height="fill_parent"
                    android:scaleType="centerInside"
                    android:src="@drawable/ic_clear"
                    android:visibility="gone"/>

                <ImageView
                    android:id="@+id/iv_show_pwd"
                    android:layout_width="40dp"
                    android:layout_height="fill_parent"
                    android:scaleType="centerInside"
                    android:src="@drawable/pass_gone"/>
            </LinearLayout>

            <View
                android:layout_width="match_parent"
                android:layout_height="1px"
                android:background="@color/e"/>

            <Button
                android:id="@+id/btn_login"
                android:layout_width="match_parent"
                android:layout_height="45dp"
                android:layout_marginBottom="10dp"
                android:layout_marginTop="21dp"
                android:background="@drawable/bg_btn_login_selected"
                android:text="@string/login"
                android:textColor="@color/white"
                android:textSize="18dp"/>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/regist"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="right"
                    android:layout_marginBottom="10dp"
                    android:layout_weight="1"
                    android:text="註冊新使用者"
                    android:textColor="#b0b8b2"
                    android:textSize="14dp"/>

                <TextView
                    android:id="@+id/forget_password"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="right"
                    android:layout_marginBottom="10dp"
                    android:layout_marginLeft="21dp"
                    android:text="@string/login_forget_pwd"
                    android:textColor="#b0b8b2"
                    android:textSize="14dp"/>
            </LinearLayout>

        </LinearLayout>

    </ScrollView>

    <LinearLayout
        android:id="@+id/service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:gravity="center"
        android:orientation="horizontal"
        android:padding="10dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:text="聯絡客服"
            android:textColor="#b0b8b2"
            android:textSize="14dp"/>

        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:background="@color/e"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:text="關於我們"
            android:textColor="#b0b8b2"
            android:textSize="14dp"/>
    </LinearLayout>

</RelativeLayout>


然後java程式碼是,

private int screenHeight = 0;//螢幕高度
private int keyHeight = 0; //軟體盤彈起後所佔高度
private float scale = 0.6f; //logo縮放比例
private int height = 0;
private void initView() {
    screenHeight = this.getResources().getDisplayMetrics().heightPixels; //獲取螢幕高度
    keyHeight = screenHeight / 3;//彈起高度為螢幕高度的1/3
}
/**
 * 禁止鍵盤彈起的時候可以滾動
 */
mScrollView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return true;
    }
});
mScrollView.addOnLayoutChangeListener(new ViewGroup.OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
      /* old是改變前的左上右下座標點值,沒有old的是改變後的左上右下座標點值
      現在認為只要控制元件將Activity向上推的高度超過了1/3螢幕高,就認為軟鍵盤彈起*/
        if (oldBottom != 0 && bottom != 0 && (oldBottom - bottom > keyHeight)) {
            Log.e("wenzhihao", "up------>" + (oldBottom - bottom));
            int dist = mContent.getBottom() - bottom;
            if (dist > 0) {
                ObjectAnimator mAnimatorTranslateY = ObjectAnimator.ofFloat(mContent, "translationY", 0.0f, -dist);
                mAnimatorTranslateY.setDuration(300);
                mAnimatorTranslateY.setInterpolator(new LinearInterpolator());
                mAnimatorTranslateY.start();
                RxAnimationUtils.zoomIn(mLogo, 0.6f, dist);
            }
            

        } else if (oldBottom != 0 && bottom != 0 && (bottom - oldBottom > keyHeight)) {
            Log.e("wenzhihao", "down------>" + (bottom - oldBottom));
            if ((mContent.getBottom() - oldBottom) > 0) {
                ObjectAnimator mAnimatorTranslateY = ObjectAnimator.ofFloat(mContent, "translationY", mContent.getTranslationY(), 0);
                mAnimatorTranslateY.setDuration(300);
                mAnimatorTranslateY.setInterpolator(new LinearInterpolator());
                mAnimatorTranslateY.start();
                //鍵盤收回後,logo恢復原來大小,位置同樣回到初始位置
                RxAnimationUtils.zoomOut(mLogo, 0.6f);
            }
            
        }
    }
});

mBtnLogin.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        RxKeyboardUtils.hideSoftInput(mContext);
    }
});
/**
 * 縮小
 *
 * @param view
 */
public static void zoomIn(final View view, float scale, float dist) {
    view.setPivotY(view.getHeight());
    view.setPivotX(view.getWidth() / 2);
    AnimatorSet mAnimatorSet = new AnimatorSet();
    ObjectAnimator mAnimatorScaleX = ObjectAnimator.ofFloat(view, "scaleX", 1.0f, scale);
    ObjectAnimator mAnimatorScaleY = ObjectAnimator.ofFloat(view, "scaleY", 1.0f, scale);
    ObjectAnimator mAnimatorTranslateY = ObjectAnimator.ofFloat(view, "translationY", 0.0f, -dist);

    mAnimatorSet.play(mAnimatorTranslateY).with(mAnimatorScaleX);
    mAnimatorSet.play(mAnimatorScaleX).with(mAnimatorScaleY);
    mAnimatorSet.setDuration(300);
    mAnimatorSet.start();
}
/**
 * f放大
 *
 * @param view
 */
public static void zoomOut(final View view, float scale) {
    view.setPivotY(view.getHeight());
    view.setPivotX(view.getWidth() / 2);
    AnimatorSet mAnimatorSet = new AnimatorSet();

    ObjectAnimator mAnimatorScaleX = ObjectAnimator.ofFloat(view, "scaleX", scale, 1.0f);
    ObjectAnimator mAnimatorScaleY = ObjectAnimator.ofFloat(view, "scaleY", scale, 1.0f);
    ObjectAnimator mAnimatorTranslateY = ObjectAnimator.ofFloat(view, "translationY", view.getTranslationY(), 0);

    mAnimatorSet.play(mAnimatorTranslateY).with(mAnimatorScaleX);
    mAnimatorSet.play(mAnimatorScaleX).with(mAnimatorScaleY);
    mAnimatorSet.setDuration(300);
    mAnimatorSet.start();
}


這段程式碼大體就是這麼實現的,動態處理sroll向上滾動問題,logo動態縮小即可解決

紀實:2016.3.3