├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── flyn │ │ └── inputmanagerhelper │ │ ├── ActionBarActivity.java │ │ ├── CustomLayoutActivity.java │ │ ├── CustomLayoutWithToolBarActivity.java │ │ ├── MainActivity.java │ │ ├── RecyclerViewActivity.java │ │ ├── ScrollViewActivity.java │ │ ├── ToolBarActivity.java │ │ ├── TranslucentLayoutActivity.java │ │ ├── helper │ │ └── InputManagerHelper.java │ │ └── view │ │ └── KeyboardListenLayout.java │ └── res │ ├── drawable │ └── timg.jpg │ ├── layout │ ├── activity_actionbar.xml │ ├── activity_custom_layout.xml │ ├── activity_custom_layout_with_toolbar.xml │ ├── activity_form.xml │ ├── activity_main.xml │ ├── activity_recycleview.xml │ ├── activity_toolbar.xml │ ├── activity_translucent_layout.xml │ └── item_string_1.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | /.idea 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 使用方法: 2 | ``` 3 | InputManagerHelper.attachToActivity(this).bind(viewGroup, view).offset(1); 4 | ``` 5 | 博客地址: 6 | [Android输入法遮挡问题的解决思路](http://www.jianshu.com/p/50c060edeaa8) 7 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion "26.0.2" 6 | defaultConfig { 7 | applicationId "com.flyn.inputmanagerhelper" 8 | minSdkVersion 15 9 | targetSdkVersion 26 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | compile 'com.android.support:appcompat-v7:26.1.0' 25 | compile "com.android.support:design:26.1.0" 26 | } 27 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Development\android-sdk-windows/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | 23 | 26 | 27 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyn/inputmanagerhelper/ActionBarActivity.java: -------------------------------------------------------------------------------- 1 | package com.flyn.inputmanagerhelper; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.widget.Button; 7 | import android.widget.LinearLayout; 8 | 9 | import com.flyn.inputmanagerhelper.helper.InputManagerHelper; 10 | 11 | public class ActionBarActivity extends AppCompatActivity { 12 | 13 | 14 | @Override 15 | protected void onCreate(@Nullable Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setContentView(R.layout.activity_actionbar); 18 | // getSupportActionBar().hide(); 19 | getSupportActionBar().setTitle("This is actionbar"); 20 | LinearLayout layout_keyboard = findViewById(R.id.layout_keyboard); 21 | Button tv_login = findViewById(R.id.tv_login); 22 | 23 | InputManagerHelper.attachToActivity(this).bind(layout_keyboard, tv_login).offset(16); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyn/inputmanagerhelper/CustomLayoutActivity.java: -------------------------------------------------------------------------------- 1 | package com.flyn.inputmanagerhelper; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.widget.Button; 7 | 8 | import com.flyn.inputmanagerhelper.helper.InputManagerHelper; 9 | import com.flyn.inputmanagerhelper.view.KeyboardListenLayout; 10 | 11 | 12 | public class CustomLayoutActivity extends AppCompatActivity { 13 | 14 | 15 | @Override 16 | protected void onCreate(@Nullable Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | // getSupportActionBar().hide(); 19 | setContentView(R.layout.activity_custom_layout); 20 | getSupportActionBar().setTitle("This is actionbar"); 21 | KeyboardListenLayout keyboardListenLayout = findViewById(R.id.layout_keyboard); 22 | Button tv_login = findViewById(R.id.tv_login); 23 | 24 | InputManagerHelper.attachToActivity(this).bind(keyboardListenLayout, tv_login).offset(16); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyn/inputmanagerhelper/CustomLayoutWithToolBarActivity.java: -------------------------------------------------------------------------------- 1 | package com.flyn.inputmanagerhelper; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.Toolbar; 7 | import android.widget.Button; 8 | 9 | import com.flyn.inputmanagerhelper.helper.InputManagerHelper; 10 | import com.flyn.inputmanagerhelper.view.KeyboardListenLayout; 11 | 12 | public class CustomLayoutWithToolBarActivity extends AppCompatActivity { 13 | 14 | 15 | @Override 16 | protected void onCreate(@Nullable Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_custom_layout_with_toolbar); 19 | Toolbar toolbar = findViewById(R.id.toolbar); 20 | toolbar.setTitle("THis is toolbar"); 21 | setSupportActionBar(toolbar); 22 | KeyboardListenLayout keyboardListenLayout = findViewById(R.id.layout_keyboard); 23 | Button tv_login = findViewById(R.id.tv_login); 24 | 25 | InputManagerHelper.attachToActivity(this).bind(keyboardListenLayout, tv_login).offset(16); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyn/inputmanagerhelper/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.flyn.inputmanagerhelper; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.View; 7 | import android.widget.Button; 8 | 9 | public class MainActivity extends AppCompatActivity implements View.OnClickListener { 10 | 11 | @Override 12 | protected void onCreate(Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | setContentView(R.layout.activity_main); 15 | Button btn_custom_layout = findViewById(R.id.btn_custom_layout); 16 | Button btn_custom_layout_with_toolbar = findViewById(R.id.btn_custom_layout_with_toolbar); 17 | Button btn_translucent_layout = findViewById(R.id.btn_translucent_layout); 18 | Button btn_form_layout = findViewById(R.id.btn_form_layout); 19 | Button btn_toolbar = findViewById(R.id.btn_toolbar); 20 | Button btn_actionBar = findViewById(R.id.btn_actionBar); 21 | Button btn_recycleview = findViewById(R.id.btn_recycleview); 22 | 23 | 24 | btn_custom_layout.setOnClickListener(this); 25 | btn_custom_layout_with_toolbar.setOnClickListener(this); 26 | btn_translucent_layout.setOnClickListener(this); 27 | btn_form_layout.setOnClickListener(this); 28 | btn_toolbar.setOnClickListener(this); 29 | btn_actionBar.setOnClickListener(this); 30 | btn_recycleview.setOnClickListener(this); 31 | } 32 | 33 | @Override 34 | public void onClick(View v) { 35 | Intent intent = new Intent(); 36 | switch (v.getId()) { 37 | case R.id.btn_custom_layout: 38 | intent.setClass(this, CustomLayoutActivity.class); 39 | break; 40 | case R.id.btn_custom_layout_with_toolbar: 41 | intent.setClass(this, CustomLayoutWithToolBarActivity.class); 42 | break; 43 | case R.id.btn_translucent_layout: 44 | intent.setClass(this, TranslucentLayoutActivity.class); 45 | break; 46 | case R.id.btn_toolbar: 47 | intent.setClass(this, ToolBarActivity.class); 48 | break; 49 | case R.id.btn_actionBar: 50 | intent.setClass(this, ActionBarActivity.class); 51 | break; 52 | case R.id.btn_form_layout: 53 | intent.setClass(this, ScrollViewActivity.class); 54 | break; 55 | case R.id.btn_recycleview: 56 | intent.setClass(this, RecyclerViewActivity.class); 57 | break; 58 | } 59 | startActivity(intent); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyn/inputmanagerhelper/RecyclerViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.flyn.inputmanagerhelper; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.LinearLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.EditText; 12 | 13 | import com.flyn.inputmanagerhelper.helper.InputManagerHelper; 14 | 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | public class RecyclerViewActivity extends AppCompatActivity { 19 | 20 | @Override 21 | protected void onCreate(@Nullable Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | // getSupportActionBar().hide(); 24 | setContentView(R.layout.activity_recycleview); 25 | RecyclerView recyclerView = findViewById(R.id.recyclerView); 26 | MyAdapter adapter = new MyAdapter(); 27 | recyclerView.setAdapter(adapter); 28 | LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); 29 | recyclerView.setLayoutManager(linearLayoutManager); 30 | List data = new ArrayList<>(); 31 | for (int i = 0; i < 50; i++) { 32 | data.add(String.valueOf(i + 1)); 33 | } 34 | adapter.setData(data); 35 | InputManagerHelper.attachToActivity(this).bind(recyclerView).offset(100); 36 | // InputManagerHelper.attachToActivity(this).bind(recyclerView); 37 | } 38 | 39 | 40 | private class MyAdapter extends RecyclerView.Adapter { 41 | 42 | List data = new ArrayList<>(); 43 | 44 | public void setData(List data) { 45 | this.data = data; 46 | notifyDataSetChanged(); 47 | } 48 | 49 | @Override 50 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 51 | View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_string_1, parent, false); 52 | return new ItemHolder(itemView); 53 | } 54 | 55 | @Override 56 | public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 57 | final ItemHolder itemViewHolder = (ItemHolder) holder; 58 | itemViewHolder.editText.setText(data.get(position)); 59 | } 60 | 61 | @Override 62 | public int getItemCount() { 63 | return data.size(); 64 | } 65 | } 66 | 67 | private class ItemHolder extends RecyclerView.ViewHolder { 68 | EditText editText; 69 | 70 | ItemHolder(View itemView) { 71 | super(itemView); 72 | editText = (EditText) itemView.findViewById(R.id.edittext); 73 | } 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyn/inputmanagerhelper/ScrollViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.flyn.inputmanagerhelper; 2 | 3 | 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.widget.ScrollView; 8 | 9 | import com.flyn.inputmanagerhelper.helper.InputManagerHelper; 10 | 11 | public class ScrollViewActivity extends AppCompatActivity { 12 | 13 | @Override 14 | protected void onCreate(@Nullable Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | // getSupportActionBar().hide(); 17 | setContentView(R.layout.activity_form); 18 | ScrollView layout_keyboard = findViewById(R.id.layout_keyboard); 19 | // InputManagerHelper.attachToActivity(this).bind(layout_keyboard); 20 | InputManagerHelper.attachToActivity(this).bind(layout_keyboard).offset(16); 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyn/inputmanagerhelper/ToolBarActivity.java: -------------------------------------------------------------------------------- 1 | package com.flyn.inputmanagerhelper; 2 | 3 | import android.os.Build; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v4.content.ContextCompat; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.support.v7.widget.Toolbar; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.view.WindowManager; 12 | import android.widget.Button; 13 | 14 | import com.flyn.inputmanagerhelper.helper.InputManagerHelper; 15 | 16 | public class ToolBarActivity extends AppCompatActivity { 17 | 18 | 19 | @Override 20 | protected void onCreate(@Nullable Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | setContentView(R.layout.activity_toolbar); 23 | Toolbar toolbar = findViewById(R.id.toolbar); 24 | toolbar.setTitleTextColor(ContextCompat.getColor(this, android.R.color.white)); 25 | toolbar.setTitle("THis is toolbar"); 26 | setSupportActionBar(toolbar); 27 | Button tv_login = findViewById(R.id.tv_login); 28 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 29 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); 30 | getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.colorPrimaryDark)); 31 | getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); 32 | } 33 | InputManagerHelper.attachToActivity(this).bind((ViewGroup) findViewById(R.id.layout_keyboard), tv_login).offset(16); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyn/inputmanagerhelper/TranslucentLayoutActivity.java: -------------------------------------------------------------------------------- 1 | package com.flyn.inputmanagerhelper; 2 | 3 | 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.ViewGroup; 8 | import android.widget.Button; 9 | 10 | import com.flyn.inputmanagerhelper.helper.InputManagerHelper; 11 | 12 | public class TranslucentLayoutActivity extends AppCompatActivity { 13 | 14 | 15 | @Override 16 | protected void onCreate(@Nullable Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_translucent_layout); 19 | ViewGroup layout_keyboard = findViewById(R.id.layout_keyboard); 20 | Button tv_login = findViewById(R.id.tv_login); 21 | 22 | InputManagerHelper.attachToActivity(this).bind(layout_keyboard, tv_login).offset(-dip2px(25) + 16); 23 | } 24 | 25 | public int dip2px(float dpValue) { 26 | final float scale = getResources().getDisplayMetrics().density; 27 | return (int) (dpValue * scale + 0.5f); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyn/inputmanagerhelper/helper/InputManagerHelper.java: -------------------------------------------------------------------------------- 1 | package com.flyn.inputmanagerhelper.helper; 2 | 3 | 4 | import android.app.Activity; 5 | import android.graphics.Rect; 6 | import android.os.Handler; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.support.v7.widget.RecyclerView; 9 | import android.util.TypedValue; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.view.ViewTreeObserver; 13 | import android.view.WindowManager; 14 | import android.widget.ScrollView; 15 | import android.widget.TextView; 16 | 17 | import com.flyn.inputmanagerhelper.R; 18 | import com.flyn.inputmanagerhelper.view.KeyboardListenLayout; 19 | 20 | public class InputManagerHelper { 21 | 22 | 23 | private Activity activity; 24 | private int lastKeyBoardHeight; 25 | private int offset; 26 | 27 | private InputManagerHelper(Activity activity) { 28 | this.activity = activity; 29 | } 30 | 31 | public static InputManagerHelper attachToActivity(Activity activity) { 32 | activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); 33 | return new InputManagerHelper(activity); 34 | } 35 | 36 | public InputManagerHelper bind(ViewGroup viewGroup, View lastVisibleView) { 37 | if (viewGroup instanceof KeyboardListenLayout) { 38 | bindKeyboardListenLayout((KeyboardListenLayout) viewGroup, lastVisibleView); 39 | } else { 40 | if (viewGroup instanceof RecyclerView || viewGroup instanceof ScrollView) { 41 | bindViewGroup(viewGroup); 42 | } else { 43 | bindLayout(viewGroup, lastVisibleView); 44 | } 45 | } 46 | return this; 47 | } 48 | 49 | public InputManagerHelper bind(ViewGroup viewGroup) { 50 | bind(viewGroup, activity.getCurrentFocus()); 51 | return this; 52 | } 53 | 54 | public InputManagerHelper offset(int offset) { 55 | this.offset = offset; 56 | return this; 57 | } 58 | 59 | private void bindKeyboardListenLayout(final KeyboardListenLayout keyboardListenLayout, final View view) { 60 | keyboardListenLayout.setOnSizeChangedListener(new KeyboardListenLayout.onSizeChangedListener() { 61 | @Override 62 | public void onChanged(final boolean showKeyboard, final int h, final int oldh) { 63 | new Handler().postDelayed(new Runnable() { 64 | @Override 65 | public void run() { 66 | View lastVisibleView = view; 67 | if (lastVisibleView == null) { 68 | lastVisibleView = activity.getCurrentFocus(); 69 | } 70 | if (showKeyboard) { 71 | //oldh代表输入法未弹出前最外层布局高度,h代表当前最外层布局高度,oldh-h可以计算出布局大小改变后输入法的高度 72 | //整个布局的高度-输入法高度=键盘最顶端处在布局中的位置,其实直接用h计算就可以,代码这么写为了便于理解 73 | int keyboardTop = oldh - (oldh - h); 74 | int[] location = new int[2]; 75 | lastVisibleView.getLocationOnScreen(location); 76 | //登录按钮顶部在屏幕中的位置+登录按钮的高度=登录按钮底部在屏幕中的位置 77 | int lastVisibleViewBottom = location[1] + lastVisibleView.getHeight(); 78 | //登录按钮底部在布局中的位置-输入法顶部的位置=需要将布局弹起多少高度 79 | int reSizeLayoutHeight = lastVisibleViewBottom - keyboardTop; 80 | //因为keyboardListenLayout的高度不包括外层的statusbar的高度和actionbar的高度 81 | //所以需要减去status bar的高度 82 | reSizeLayoutHeight -= getStatusBarHeight(); 83 | //如果界面里有actionbar并且处于显示状态则需要少减去actionbar的高度 84 | if (null != (((AppCompatActivity) activity).getSupportActionBar()) && (((AppCompatActivity) activity).getSupportActionBar()).isShowing()) { 85 | reSizeLayoutHeight -= getActionBarHeight(); 86 | } 87 | //设置登录按钮与输入法之间间距 88 | reSizeLayoutHeight += offset; 89 | if (reSizeLayoutHeight > 0) 90 | keyboardListenLayout.setPadding(0, -reSizeLayoutHeight, 0, 0); 91 | } else { 92 | //还原布局 93 | keyboardListenLayout.setPadding(0, 0, 0, 0); 94 | } 95 | } 96 | }, 50); 97 | } 98 | }); 99 | } 100 | 101 | private void bindLayout(final ViewGroup viewGroup, final View view) { 102 | viewGroup.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 103 | @Override 104 | public void onGlobalLayout() { 105 | new Handler().postDelayed(new Runnable() { 106 | @Override 107 | public void run() { 108 | View lastVisibleView = view; 109 | if (lastVisibleView == null) { 110 | lastVisibleView = activity.getCurrentFocus(); 111 | } 112 | //获得屏幕高度 113 | int screenHeight = viewGroup.getRootView().getHeight(); 114 | //r.bottom - r.top计算出输入法弹起后viewGroup的高度,屏幕高度-viewGroup高度即为键盘高度 115 | Rect r = new Rect(); 116 | viewGroup.getWindowVisibleDisplayFrame(r); 117 | int keyboardHeight = screenHeight - (r.bottom - r.top); 118 | //当设置layout_keyboard设置完padding以后会重绘布局再次执行onGlobalLayout() 119 | //所以判断如果键盘高度未改变就不执行下去 120 | if (keyboardHeight == lastKeyBoardHeight) { 121 | return; 122 | } 123 | lastKeyBoardHeight = keyboardHeight; 124 | if (keyboardHeight < 300) { 125 | //键盘关闭后恢复布局 126 | viewGroup.setPadding(0, 0, 0, 0); 127 | } else { 128 | //计算出键盘最顶端在布局中的位置 129 | int keyboardTop = screenHeight - keyboardHeight; 130 | int[] location = new int[2]; 131 | lastVisibleView.getLocationOnScreen(location); 132 | //获取登录按钮底部在屏幕中的位置 133 | int lastVisibleViewBottom = location[1] + lastVisibleView.getHeight(); 134 | //登录按钮底部在布局中的位置-输入法顶部的位置=需要将布局弹起多少高度 135 | int reSizeLayoutHeight = lastVisibleViewBottom - keyboardTop; 136 | //需要多弹起一个StatusBar的高度 137 | reSizeLayoutHeight -= getStatusBarHeight(); 138 | //设置登录按钮与输入法之间间距 139 | reSizeLayoutHeight += offset; 140 | if (reSizeLayoutHeight > 0) { 141 | viewGroup.setPadding(0, -reSizeLayoutHeight, 0, 0); 142 | } 143 | } 144 | } 145 | }, 50); 146 | } 147 | }); 148 | } 149 | 150 | private void bindViewGroup(final ViewGroup viewGroup) { 151 | viewGroup.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 152 | @Override 153 | public void onGlobalLayout() { 154 | new Handler().postDelayed(new Runnable() { 155 | @Override 156 | public void run() { //获得屏幕高度 157 | int screenHeight = viewGroup.getRootView().getHeight(); 158 | //r.bottom - r.top计算出输入法弹起后viewGroup的高度,屏幕高度-viewGroup高度即为键盘高度 159 | Rect r = new Rect(); 160 | viewGroup.getWindowVisibleDisplayFrame(r); 161 | int keyboardHeight = screenHeight - (r.bottom - r.top); 162 | //当设置layout_keyboard设置完padding以后会重绘布局再次执行onGlobalLayout() 163 | //所以判断如果键盘高度未改变就不执行下去 164 | if (keyboardHeight == lastKeyBoardHeight) { 165 | return; 166 | } 167 | lastKeyBoardHeight = keyboardHeight; 168 | View view = activity.getWindow().getCurrentFocus(); 169 | if (keyboardHeight > 300 && null != view) { 170 | if (view instanceof TextView) { 171 | //计算出键盘最顶端在布局中的位置 172 | int keyboardTop = screenHeight - keyboardHeight; 173 | int[] location = new int[2]; 174 | view.getLocationOnScreen(location); 175 | //获取登录按钮底部在屏幕中的位置 176 | int viewBottom = location[1] + view.getHeight(); 177 | //比较输入框与键盘的位置关系,如果输入框在键盘之上的位置就不做处理 178 | if (viewBottom <= keyboardTop) 179 | return; 180 | //需要滚动的距离即为输入框底部到键盘的距离 181 | int reSizeLayoutHeight = viewBottom - keyboardTop; 182 | reSizeLayoutHeight -= getStatusBarHeight(); 183 | reSizeLayoutHeight += offset; 184 | if (viewGroup instanceof ScrollView) { 185 | ((ScrollView) viewGroup).smoothScrollBy(0, reSizeLayoutHeight); 186 | } else if (viewGroup instanceof RecyclerView) { 187 | ((RecyclerView) viewGroup).smoothScrollBy(0, reSizeLayoutHeight); 188 | } 189 | } 190 | } 191 | } 192 | }, 50); 193 | } 194 | }); 195 | } 196 | 197 | 198 | private int getStatusBarHeight() { 199 | int result = 0; 200 | int resId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android"); 201 | if (resId > 0) { 202 | result = activity.getResources().getDimensionPixelOffset(resId); 203 | } 204 | return result; 205 | } 206 | 207 | private int getActionBarHeight() { 208 | if (null != (((AppCompatActivity) activity).getSupportActionBar())) { 209 | //如果界面里有actionbar则需要多向上弹起一个actionbar的高度 210 | TypedValue typedValue = new TypedValue(); 211 | if (activity.getTheme().resolveAttribute(R.attr.actionBarSize, typedValue, true)) { 212 | return TypedValue.complexToDimensionPixelSize(typedValue.data, activity.getResources().getDisplayMetrics()); 213 | } 214 | } 215 | return 0; 216 | } 217 | 218 | } 219 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyn/inputmanagerhelper/view/KeyboardListenLayout.java: -------------------------------------------------------------------------------- 1 | package com.flyn.inputmanagerhelper.view; 2 | 3 | 4 | import android.content.Context; 5 | import android.util.AttributeSet; 6 | import android.widget.RelativeLayout; 7 | 8 | public class KeyboardListenLayout extends RelativeLayout { 9 | 10 | private onSizeChangedListener mChangedListener; 11 | 12 | public KeyboardListenLayout(Context context) { 13 | super(context); 14 | } 15 | 16 | public KeyboardListenLayout(Context context, AttributeSet attrs) { 17 | super(context, attrs); 18 | } 19 | 20 | public KeyboardListenLayout(Context context, AttributeSet attrs, int defStyleAttr) { 21 | super(context, attrs, defStyleAttr); 22 | } 23 | 24 | @Override 25 | protected void onSizeChanged(int w, int h, int oldw, int oldh) { 26 | super.onSizeChanged(w, h, oldw, oldh); 27 | if (null != mChangedListener && 0 != oldw && 0 != oldh) { 28 | boolean showKeyboard = h < oldh; 29 | mChangedListener.onChanged(showKeyboard, h, oldh); 30 | } 31 | } 32 | 33 | public void setOnSizeChangedListener(onSizeChangedListener listener) { 34 | mChangedListener = listener; 35 | } 36 | 37 | public interface onSizeChangedListener { 38 | void onChanged(boolean showKeyboard, int h, int oldh); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/timg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imflyn/InputManagerHelper/e20db11dcd1d112fb3e4fbc47cc873329ca08a4e/app/src/main/res/drawable/timg.jpg -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_actionbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 17 | 18 | 24 | 25 | 37 | 38 | 43 | 44 | 45 | 51 | 52 | 53 | 65 | 66 | 71 | 72 | 73 | 79 | 80 |