Android之全屏下软键盘弹出布局移动问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/I_do_can/article/details/71159198

本文主要记录一些零碎的东西

主要记录android 下 全屏界面时 软键盘弹出后布局移动的解决方案

先看看正常的布局(hellword文字在屏幕正中间)


全屏下软键盘弹出后结果


可以看见整个布局都上去了,这样肯定不好,想背景不移动,只是输入框移动,效果图


看看怎么实现的吧

布局文件 背景和需要移动的控件肯定是需要分开的

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.cl.slack.fullscreensoftkeyboard.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Hello World!"
        />

    <!--
        需要移动布局的父布局
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    -->
    <LinearLayout
        android:id="@+id/move_root"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <!-- 需要移动的布局 -->
        <LinearLayout
            android:id="@+id/move_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom">

            <EditText
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="跟随软键盘上下移动"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="确定"/>
        </LinearLayout>
    </LinearLayout>

</FrameLayout>

全部测试代码,其他地方不要要任何改动

核心部分是 ViewTreeObserver.OnGlobalLayoutListener

import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;

/**
 * created by slack
 * on 17/5/4 上午10:39
 * 解决全屏下 软键盘弹出布局移动问题
 * 其中 moveRoot 是 需要移动布局的父布局(最好全屏)
 *      moveView 是需要移动的布局
 */
public class MainActivity extends AppCompatActivity {

    View moveRoot;
    View moveView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // full screen
        this.getWindow().setFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        moveRoot = findViewById(R.id.move_root);
        moveView = findViewById(R.id.move_view);

        addSoftKeyBoardListener(moveRoot,moveView);

    }

    private ViewTreeObserver.OnGlobalLayoutListener mSoftKeyBoardListener;

    private class SoftKeyBoardListener implements ViewTreeObserver.OnGlobalLayoutListener {

        private View root;
        private View view;

        int lastHeight = 0;
        int lastBottom = -1;

        SoftKeyBoardListener(View r,View v) {
            root = r;
            view = v;
        }

        @Override
        public void onGlobalLayout() {
            Rect rect = new Rect();
            root.getWindowVisibleDisplayFrame(rect);
            if (lastBottom == -1) {
                lastBottom = rect.bottom;
                return;
            }

            int nb = rect.bottom;
            int ob = lastBottom;

            if (nb < ob) {
                // 键盘显示了, 滑上去
                int[] location = new int[2];
                view.getLocationInWindow(location);
                int scrollHeight = (location[1] + view.getHeight()) - nb;

                root.scrollTo(0, scrollHeight);
                lastHeight = scrollHeight;
            }
            else if (nb > ob) {
                // 键盘隐藏了, 滑下来
                root.scrollTo(0, 0);
            }

            if (nb != ob) {
                lastBottom = nb;
            }
        }
    }

    public void removeSoftKeyBoardListener(@NonNull View root) {
        if(mSoftKeyBoardListener != null){
            root.getViewTreeObserver().removeOnGlobalLayoutListener(mSoftKeyBoardListener);
        }
    }

    public void addSoftKeyBoardListener(final View root, final View view) {
        mSoftKeyBoardListener = new SoftKeyBoardListener(root,view);
        root.getViewTreeObserver().addOnGlobalLayoutListener(mSoftKeyBoardListener);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        removeSoftKeyBoardListener(moveRoot);
    }
}

--------网上发现一段其他的计算弹出软键盘高度的代码,更新-----------

public void addOnSoftKeyBoardVisibleListener(final View root, final IKeyBoardVisibleListener listener) {
        root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect rect = new Rect();
                root.getWindowVisibleDisplayFrame(rect);
                //计算出可见屏幕的高度
                int displayHight = rect.bottom - rect.top;
                //获得屏幕整体的高度
                int hight = root.getHeight();
                //获得键盘高度
                int keyboardHeight = hight-displayHight;
                boolean visible = (double) displayHight / hight < 0.8;
                if(visible){
                    root.scrollTo(0, keyboardHeight);
                }else {
                    root.scrollTo(0, 0);
                }
                if(visible != isVisibleForLast){
                    listener.onSoftKeyBoardVisible(visible,keyboardHeight );
                }
                isVisibleForLast = visible;
            }
        });
    }

    interface IKeyBoardVisibleListener{
        void onSoftKeyBoardVisible(boolean visible , int windowBottom);
    }

修改了一下,添加了一个自动滑动,onGlobalLayout()里只要有view 滑动了,整个布局的随着软键盘弹出的滑动就不会执行了,

可以计算出类似华为这样的有底部导航栏的手机的软键盘弹出高度。


猜你喜欢

转载自blog.csdn.net/I_do_can/article/details/71159198