我在清单中使用了android:windowSoftInputMode ="adjustResize"来防止键盘隐藏活动按钮.它可以工作,但是当键盘打开时,我的按钮会向上移动.它有点跳跃,我想知道 - 我可以有任何动画来顺利过渡吗?
fllo.. 6
该方法setSoftInputMode(int)
不能被覆盖,它的实现是在Window
类内部,我认为无法用您自己的方法替换当前窗口。您也无法对此进行管理WindowManager
。
您可以在上创建一个侦听器,ViewGroup
并在SoftKeyboard
打开和关闭时捕获修改的布局。实际上,当SKB出现时,容器的布局将重新绘制并更改其高度。通过此事件,您可以设法设置一个Animation
on view子级并产生平滑效果。
编辑:也可以通过在rootview上使用GlobalLayoutListener
解决方案,而不是(下面显示的解决方案:)创建自定义视图组类。
您必须创建自己的视图组并将其作为布局中的父容器。它会实现,这将在UI类来处理接口(Activity
,Fragment
,等等)。我发现此博客可检测所有版本(〜)上SKB上的事件。据此,这是处理高度变化的视图组的类:
public class ContainerViewHandler extends RelativeLayout { private boolean isKeyboardShown; private onKeyboardStateChange listener; public ContainerViewHandler(Context context) { super(context); } public ContainerViewHandler(Context context, AttributeSet attrs) { super(context, attrs); } public ContainerViewHandler(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setKeyboardStateListener(onKeyboardStateChange listener) { this.listener = listener; } // Callbacks public interface onKeyboardStateChange { void onKeyboardShow(); void onKeyboardHide(); } @Override public boolean dispatchKeyEventPreIme(@NonNull KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { // Keyboard is hiding if (isKeyboardShown) { isKeyboardShown = false; listener.onKeyboardHide(); } } return super.dispatchKeyEventPreIme(event); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int proposedHeight = MeasureSpec.getSize(heightMeasureSpec); final int actualHeight = getHeight(); if (actualHeight > proposedHeight) { // Keyboard is showing if (!isKeyboardShown) { isKeyboardShown = true; listener.onKeyboardShow(); } } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } }
现在,您必须在布局中添加此视图组(例如
)。然后,您必须setKeyboardStateListener
在活动中实现上述接口,如下所示:
ContainerViewHandler containerView = (ContainerViewHandler) findViewById(R.id.container_view); containerView.setKeyboardStateListener(new ContainerHandler.onKeyboardStateChange() { @Override public void onKeyboardShow() { Log.v("onKeyboardShow()", "SoftKeyboard is showing. Hello!"); } @Override public void onKeyboardHide() { Log.v("onKeyboardHide()", "SoftKeyboard is hiding, Bye bye!"); } });
因此,您可以管理不同的动画来处理和防止按钮直接跳到SKB上方。为了测试这一点,我尝试重现反弹效果:
我的实现如下所示:
containerView.setKeyboardStateListener(new ContainerViewHandler.onKeyboardStateChange() { @Override public void onKeyboardShow() { setAnimationUp(); } @Override public void onKeyboardHide() { setAnimationDown(); } }); private void setAnimationUp() { footerButton.setVisibility(View.GONE); float dpY = AppUtils.convertPxToDp(20, this); // custom conversion method Animation a1 = new TranslateAnimation(0, 0, footerButton.getHeight() * 4, -(dpY)); a1.setDuration(250); a1.setFillAfter(true); final Animation a2 = new TranslateAnimation(0, 0, -(dpY), 0); a2.setDuration(320); a2.setFillAfter(true); a1.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { footerButton.setVisibility(View.VISIBLE); } @Override public void onAnimationEnd(Animation animation) { footerButton.startAnimation(a2); } @Override public void onAnimationRepeat(Animation animation) { } }); footerButton.startAnimation(a1); } private void setAnimationDown() { float dpY = AppUtils.convertPxToDp(30, this); // custom conversion method Animation b1 = new TranslateAnimation(0, 0, -(dpY), dpY); b1.setDuration(300); b1.setFillAfter(true); final Animation b2 = new TranslateAnimation(0, 0, dpY, 0); b2.setDuration(320); b2.setFillAfter(true); b1.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { footerButton.startAnimation(b2); } @Override public void onAnimationRepeat(Animation animation) { } }); footerButton.startAnimation(b1); }
我首先在第一个回调中设置两个动画(a1,a2):
a1:从SKB(大约4xbutton's height
)下方(之后)开始,直至其20dp
上方,
a2:从处开始20dp
并返回0dp
(正常位置)。
在第二个回调中还有另外两个(b1,b2):
b1:从按钮30dp
顶部上方开始,然后向下至30dp
父容器外部,
b2:最后,从30dp
外到0dp
(初始位置)。
PS:别忘了adjustResize
在清单中使用并使内容(例如,我的测试中的edittext)above
成为页脚按钮,该按钮必须alignParentBottom
为true。
该方法setSoftInputMode(int)
不能被覆盖,它的实现是在Window
类内部,我认为无法用您自己的方法替换当前窗口。您也无法对此进行管理WindowManager
。
您可以在上创建一个侦听器,ViewGroup
并在SoftKeyboard
打开和关闭时捕获修改的布局。实际上,当SKB出现时,容器的布局将重新绘制并更改其高度。通过此事件,您可以设法设置一个Animation
on view子级并产生平滑效果。
编辑:也可以通过在rootview上使用GlobalLayoutListener
解决方案,而不是(下面显示的解决方案:)创建自定义视图组类。
您必须创建自己的视图组并将其作为布局中的父容器。它会实现,这将在UI类来处理接口(Activity
,Fragment
,等等)。我发现此博客可检测所有版本(〜)上SKB上的事件。据此,这是处理高度变化的视图组的类:
public class ContainerViewHandler extends RelativeLayout { private boolean isKeyboardShown; private onKeyboardStateChange listener; public ContainerViewHandler(Context context) { super(context); } public ContainerViewHandler(Context context, AttributeSet attrs) { super(context, attrs); } public ContainerViewHandler(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setKeyboardStateListener(onKeyboardStateChange listener) { this.listener = listener; } // Callbacks public interface onKeyboardStateChange { void onKeyboardShow(); void onKeyboardHide(); } @Override public boolean dispatchKeyEventPreIme(@NonNull KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { // Keyboard is hiding if (isKeyboardShown) { isKeyboardShown = false; listener.onKeyboardHide(); } } return super.dispatchKeyEventPreIme(event); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int proposedHeight = MeasureSpec.getSize(heightMeasureSpec); final int actualHeight = getHeight(); if (actualHeight > proposedHeight) { // Keyboard is showing if (!isKeyboardShown) { isKeyboardShown = true; listener.onKeyboardShow(); } } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } }
现在,您必须在布局中添加此视图组(例如<com.package.name.ContainerViewHandler .../>
)。然后,您必须setKeyboardStateListener
在活动中实现上述接口,如下所示:
ContainerViewHandler containerView = (ContainerViewHandler) findViewById(R.id.container_view); containerView.setKeyboardStateListener(new ContainerHandler.onKeyboardStateChange() { @Override public void onKeyboardShow() { Log.v("onKeyboardShow()", "SoftKeyboard is showing. Hello!"); } @Override public void onKeyboardHide() { Log.v("onKeyboardHide()", "SoftKeyboard is hiding, Bye bye!"); } });
因此,您可以管理不同的动画来处理和防止按钮直接跳到SKB上方。为了测试这一点,我尝试重现反弹效果:
我的实现如下所示:
containerView.setKeyboardStateListener(new ContainerViewHandler.onKeyboardStateChange() { @Override public void onKeyboardShow() { setAnimationUp(); } @Override public void onKeyboardHide() { setAnimationDown(); } }); private void setAnimationUp() { footerButton.setVisibility(View.GONE); float dpY = AppUtils.convertPxToDp(20, this); // custom conversion method Animation a1 = new TranslateAnimation(0, 0, footerButton.getHeight() * 4, -(dpY)); a1.setDuration(250); a1.setFillAfter(true); final Animation a2 = new TranslateAnimation(0, 0, -(dpY), 0); a2.setDuration(320); a2.setFillAfter(true); a1.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { footerButton.setVisibility(View.VISIBLE); } @Override public void onAnimationEnd(Animation animation) { footerButton.startAnimation(a2); } @Override public void onAnimationRepeat(Animation animation) { } }); footerButton.startAnimation(a1); } private void setAnimationDown() { float dpY = AppUtils.convertPxToDp(30, this); // custom conversion method Animation b1 = new TranslateAnimation(0, 0, -(dpY), dpY); b1.setDuration(300); b1.setFillAfter(true); final Animation b2 = new TranslateAnimation(0, 0, dpY, 0); b2.setDuration(320); b2.setFillAfter(true); b1.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { footerButton.startAnimation(b2); } @Override public void onAnimationRepeat(Animation animation) { } }); footerButton.startAnimation(b1); }
我首先在第一个回调中设置两个动画(a1,a2):
a1:从SKB(大约4xbutton's height
)下方(之后)开始,直至其20dp
上方,
a2:从处开始20dp
并返回0dp
(正常位置)。
在第二个回调中还有另外两个(b1,b2):
b1:从按钮30dp
顶部上方开始,然后向下至30dp
父容器外部,
b2:最后,从30dp
外到0dp
(初始位置)。
PS:别忘了adjustResize
在清单中使用并使内容(例如,我的测试中的edittext)above
成为页脚按钮,该按钮必须alignParentBottom
为true。