本文主要记录一些零碎的东西
主要记录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 滑动了,整个布局的随着软键盘弹出的滑动就不会执行了,
可以计算出类似华为这样的有底部导航栏的手机的软键盘弹出高度。