Android 软键盘弹出自动移动布局
2016-06-21 15:50
465 查看
2行代码搞定软键盘布局上移
当我们在使用登录界面的时候,软键盘弹出经常会挡住输入框或者登录按钮
一般应用都没有处理,处理的也是很粗糙,所以我写了一个自定义控件解决该问题。
想移动谁就移动谁,so easy !!!!!
/** * 类描述: 监听布局Layout变化,进行移动整体布局的自定义控件 * 创建人: chenyang * QQ: 454725164 * 邮箱: inke88@163.com * 创建时间: 2016年06月17日 15时35分 * 修改人: * 修改时间: * 修改备注: * 版本: */ public class KeyboardMoveLayout extends LinearLayout { private OnSizeChangedListener mChangedListener; private boolean isShowKeyboard = false; public KeyboardMoveLayout(Context context) { super(context); } public KeyboardMoveLayout(Context context, AttributeSet attrs) { super(context, attrs); } public KeyboardMoveLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if (null != mChangedListener && 0 != oldw && 0 != oldh) { if (h < oldh) { isShowKeyboard = true; } else { isShowKeyboard = false; } mChangedListener.onChanged(isShowKeyboard); } } public void setOnSizeChangedListener(OnSizeChangedListener listener) { mChangedListener = listener; } public interface OnSizeChangedListener { void onChanged(boolean showKeyboard); } }
上面的KeyboardMoveLayout自定义控件主要用于监听软键盘的弹出或者关闭,该自定义控件一般放在一级根布局或者二级根布局。
想移动谁,就把ScrollView包裹在谁身上
<?xml version="1.0" encoding="utf-8"?> <test.inke.com.test.KeyboardMoveLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/ll" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="test.inke.com.test.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:background="#ff0000"></LinearLayout> <ScrollView android:id="@+id/sc" android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true"> <LinearLayout android:id="@+id/ll_move" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <EditText android:id="@+id/et1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="40dp" android:text="1111" /> <EditText android:id="@+id/et2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="2222" /> <EditText android:id="@+id/et3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="3333" /> <EditText android:id="@+id/et4" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="4444" /> <EditText android:id="@+id/et5" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="5555" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="end" android:maxLines="2" android:text="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxvxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" /> <Button android:id="@+id/bt" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:text="xxxxxxxx" /> </LinearLayout> </ScrollView> </test.inke.com.test.KeyboardMoveLayout>
上面是demo的xml布局。
以下是自定义控件的核心工具类
/** * 类描述: 自动移动的工具类 * 创建人: chenyang * QQ: 454725164 * 邮箱: inke88@163.com * 创建时间: 2016年06月17日 15时40分 * 修改人: * 修改时间: * 修改备注: * 版本: */ public class AutoMoveUtis { public static AutoMoveUtis autoMoveUtis; private AutoMoveUtis() { } public static AutoMoveUtis getInstance() { if (autoMoveUtis == null) { synchronized (AutoMoveUtis.class) { if (autoMoveUtis == null) { autoMoveUtis = new AutoMoveUtis(); } } } return autoMoveUtis; } //保存View和移动的距离信息 public static Map<Integer, MoveLayoutModel> moveMaps = new HashMap<Integer, MoveLayoutModel>(); private int currentFocus = -1;//当前焦点 private int oldFocus = -1;//上一次焦点 private Handler handler = new Handler(); private boolean isAlreadJudgeMove;//是否已经判断移动,防止多次移动,损耗性能。 private int delayTime = 100;//延迟执行滚动时间。 private ScrollView scrollView; /** * 监听软件盘是否弹出 * * @param rootView * @param scrollView */ public void setRootAndScrollView(KeyboardMoveLayout rootView, ScrollView scrollView) { this.scrollView = scrollView; rootView.setOnSizeChangedListener(new KeyboardMoveLayout.OnSizeChangedListener() { @Override public void onChanged(boolean showKeyboard) { if (showKeyboard && !isAlreadJudgeMove) { moveHeight(); } } }); } /** * 监听焦点变化 */ public View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener() { @Override public void onFocusChange(View view, boolean isFocused) { if (isFocused) { currentFocus = view.getId();//获取view的id if (AutoMoveUtis.moveMaps.containsKey(view.getId())) { //焦点变化在触发移动 if (oldFocus != currentFocus) { isAlreadJudgeMove = true; moveHeight();//移动 } } } else { // 此处为失去焦点时的处理内容 } } }; /** * 默认移动自身EditText的高度 * * @param view */ public void setAutoMoveEditText(final EditText view) { view.post(new Runnable() { @Override public void run() { moveMaps.put(view.getId(), new MoveLayoutModel(view.getId(), view.getHeight())); } }); view.setOnFocusChangeListener(onFocusChangeListener); } /** * 移动自身EditText的高度的倍数 * * @param view * @param ratioHeight */ public void setAutoMoveEditText(final EditText view, final float ratioHeight) { view.post(new Runnable() { @Override public void run() { moveMaps.put(view.getId(), new MoveLayoutModel(view.getId(), (int) (view.getHeight() * ratioHeight))); } }); view.setOnFocusChangeListener(onFocusChangeListener); } /** * 移动随意的距离 * * @param view * @param moveDistance */ public void setAutoMoveEditText(final EditText view, final int moveDistance) { view.post(new Runnable() { @Override public void run() { moveMaps.put(view.getId(), new MoveLayoutModel(view.getId(), moveDistance)); } }); view.setOnFocusChangeListener(onFocusChangeListener); } /** * 移动到ScrollView的底部 * * @param view */ public void setAutoMoveButtomEditText(final EditText view) { view.post(new Runnable() { @Override public void run() { moveMaps.put(view.getId(), new MoveLayoutModel(view.getId(), view.getHeight(), MoveLayoutModel.MOVE_BOTTOM)); } }); view.setOnFocusChangeListener(onFocusChangeListener); } /** * 移动高度 */ private void moveHeight() { //初始状态不移动 if (currentFocus == -1) { return; } //根据设置的模式,进行移动高度或者移动到底部 if (AutoMoveUtis.moveMaps.containsKey(currentFocus)) { MoveLayoutModel moveLayoutModel = AutoMoveUtis.moveMaps.get(currentFocus); if (moveLayoutModel.getMoveStatus() == MoveLayoutModel.MOVE_DISTANCE) { moveDistance(moveLayoutModel.getMoveDistance()); } else if (moveLayoutModel.getMoveStatus() == MoveLayoutModel.MOVE_BOTTOM) { moveButtom(); } } oldFocus = currentFocus; } // 移动距离 private void moveDistance(final int moveHeight) { handler.postDelayed(new Runnable() { @Override public void run() { isAlreadJudgeMove = false; scrollView.scrollTo(0, moveHeight);//滚动到底部 } }, delayTime); } // 移动到底部 private void moveButtom() { handler.postDelayed(new Runnable() { @Override public void run() { isAlreadJudgeMove = false; scrollView.fullScroll(ScrollView.FOCUS_DOWN); } }, delayTime); } }
最后需要在Activity中增加<span style="font-size:32px;color:#ff0000;">android:windowSoftInputMode="adjustResize|stateHidden"</span>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="test.inke.com.test">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:windowSoftInputMode="adjustResize|stateHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
测试类:
/** * 类描述: * 创建人: chenyang * QQ: 454725164 * 邮箱: inke88@163.com * 创建时间: 2016年06月17日 15时31分 * 修改人: * 修改时间: * 修改备注: * 版本: */ public class MainActivity extends Activity { private EditText et1, et2, et3, et4, et5; private ScrollView scrollView; private KeyboardMoveLayout rootView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); rootView = (KeyboardMoveLayout) findViewById(R.id.ll); scrollView = (ScrollView) findViewById(R.id.sc); et1 = (EditText) findViewById(R.id.et1); et2 = (EditText) findViewById(R.id.et2); et3 = (EditText) findViewById(R.id.et3); et4 = (EditText) findViewById(R.id.et4); et5 = (EditText) findViewById(R.id.et5); // 注入根布局和ScrollView控件 AutoMoveUtis.getInstance().setRootAndScrollView(rootView, scrollView); //焦点移动到哪个EditText,进行布局滑动就注入哪个EditText AutoMoveUtis.getInstance().setAutoMoveEditText(et1);//移动EditText自身高度 AutoMoveUtis.getInstance().setAutoMoveEditText(et2, 2f);//移动EditText自身高度的倍数 AutoMoveUtis.getInstance().setAutoMoveEditText(et3, 30);//移动随意高度 AutoMoveUtis.getInstance().setAutoMoveEditText(et4, 150);//移动随意高度 AutoMoveUtis.getInstance().setAutoMoveButtomEditText(et5);//移动到底部 } }
相关文章推荐
- Android-->EventBus 3.0新版使用说明(及其使用方法)
- Android系统编译与测试
- 框架模式 MVC 在Android中的使用
- 毕设项目总结之序章
- android Intent调用地图应用客户端
- 【Android】Activity之间的切换效果定义
- Android Gson解析json详解
- Android Studio 2.2新特性(Google 2016 I/O)
- Android系统中默认值的意义列表
- android listview的优化
- Eclipse代码导入到AndroidStudio的两种方式
- Android Studio使用心得
- Android蓝牙开发
- Android之测试代码实现步骤:
- Android 禁止Viewpager左右滑动功能
- Android 自定义ViewGroup控件
- 【Android】【ListView】The content of the adapter has changed
- 【Android】【ListView】The content of the adapter has changed
- 【Android】【ListView】The content of the adapter has changed
- 【Android】【ListView】The content of the adapter has changed