动画AdjustResize [英] AdjustResize with animation

查看:181
本文介绍了动画AdjustResize的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用的android:windowSoftInputMode =adjustResize在清单以prevent键盘从隐藏的活动按钮。它的工作原理,但键盘打开时,我的按钮向上移动。这是一个有点神经质,我想知道 - 我能有什么动画,为平稳过渡

 <活动
        机器人:活动名称=
        机器人:screenOrientation =画像
        机器人:windowSoftInputMode =adjustResize>
< /活性GT;


解决方案

该方法 setSoftInputMode(INT)不能overrided,它的实施是在窗口类,我不认为这是可能由您自己来替换当前窗口。您无法从管理这个窗口管理器了。结果
你可以在的ViewGroup 创建一个侦听器,赶上修改的布局时, SoftKeyboard 的开闭。事实上,当SKB显示出来,容器的布局重绘并改变其高度。从这个事件中,你可以设法设置动画的意见的孩子,使流畅的效果。

编辑:使用 GlobalLayoutListener 上rootview解决方案 是不是(以下psented解决方案$ p $)创建一个自定义的ViewGroup类也是可能的。

您必须创建自己的ViewGroup,并使其作为布局的父容器。这将实现,这将在UI类来处理接口(活动片段,等等)。我发现这个博客上检测的事件SKB为(〜)所有版本的。据此,这里是一个ViewGroup的类来处理高度的变化:

 公共类ContainerViewHandler扩展RelativeLayout的{    私人布尔isKeyboardShown;
    私人onKeyboardStateChange侦听器;    公共ContainerViewHandler(上下文的背景下){
        超级(上下文);
    }    公共ContainerViewHandler(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);
    }    公共ContainerViewHandler(上下文的背景下,ATTRS的AttributeSet,诠释defStyle){
        超(背景下,ATTRS,defStyle);
    }    公共无效setKeyboardStateListener(onKeyboardStateChange监听){
        this.listener =侦听器;
    }    //回调
    公共接口onKeyboardStateChange {
        无效onKeyboardShow();
        无效onKeyboardHide();
    }    @覆盖
    公共布尔dispatchKeyEvent $ P $宗座外方传教会(@NonNull KeyEvent的事件){
        如果(event.getKey code()== KeyEvent.KEY code_BACK){
            //键盘是隐藏
            如果(isKeyboardShown){
                isKeyboardShown = FALSE;
                listener.onKeyboardHide();
            }
        }
        返回super.dispatchKeyEvent $ P $宗座外方传教会(事件);
    }    @覆盖
    保护无效onMeasure(INT widthMeasureSpec,诠释heightMeasureSpec){
        最终诠释proposedHeight = MeasureSpec.getSize(heightMeasureSpec);
        最终诠释的ActualHeight =的getHeight();
        如果(的ActualHeight> proposedHeight){
            //键盘正显示出
            如果(!isKeyboardShown){
                isKeyboardShown = TRUE;
                listener.onKeyboardShow();
            }
        }
        super.onMeasure(widthMeasureSpec,heightMeasureSpec);
    }
}

现在,你已经添加在此布局的ViewGroup(如< com.package.name.ContainerViewHandler ... /> )。然后,你必须实现上述接口 setKeyboardStateListener 活动中,如下所示:

  ContainerViewHandler containerView =
          (ContainerViewHandler)findViewById(R.id.container_view);
containerView.setKeyboardStateListener(新ContainerHandler.onKeyboardStateChange(){
    @覆盖
    公共无效onKeyboardShow(){
        Log.v(onKeyboardShow(),SoftKeyboard是显示你好!);
    }    @覆盖
    公共无效onKeyboardHide(){
        Log.v(onKeyboardHide(),SoftKeyboard是隐藏,拜拜!);
    }
});

因此​​,您可以管理不同的动画处理和prevent的按钮,上面的SKB跳跃直接。为了验证这一点,我通过给一个反弹效果测试:

我开始通过设置两个动画(A1,A2)在第一回调:


  • A1 :下启动(后面)的SKB(约 4xbutton的高度)和高达 20dp 上面,

  • A2 :在 20dp 启动,并返回到 0dp (正常位置)。

和另外两个人(B1,B2)在第二个回调:


  • B1 :地方开始按钮达到 30dp 在顶部和下井 30dp 父容器外,

  • B2 :finaly,从 30dp 到`0dp(初始位置)。

这是我实现的样子:

  containerView.setKeyboardStateListener(新ContainerViewHandler.onKeyboardStateChange(){
    @覆盖
    公共无效onKeyboardShow(){
        setAnimationUp();
    }    @覆盖
    公共无效onKeyboardHide(){
        setAnimationDown();
    }
});私人无效setAnimationUp(){
    footerButton.setVisibility(View.GONE);
    浮DPY = AppUtils.convertPxToDp(20本); //自定义的转换方法    动画A1 =新TranslateAnimation(0,0,footerButton.getHeight()* 4, - (DPY));
    a1.setDuration(250);
    a1.setFillAfter(真);    最后动画A2 =新TranslateAnimation(0,0, - (DPY),0);
    a2.setDuration(320);
    a2.setFillAfter(真);    a1.setAnimationListener(新Animation.AnimationListener(){
        @覆盖
        公共无效onAnimationStart(动画动画){
            footerButton.setVisibility(View.VISIBLE);
        }        @覆盖
        公共无效onAnimationEnd(动画动画){
            footerButton.startAnimation(A2);
        }        @覆盖
        公共无效onAnimationRepeat(动画动画){}
    });    footerButton.startAnimation(A1);
}私人无效setAnimationDown(){
    浮DPY = AppUtils.convertPxToDp(30,这一点); //自定义的转换方法
    动画B1 =新TranslateAnimation(0,0, - (DPY),DPY);
    b1.setDuration(300);
    b1.setFillAfter(真);    最后动画B2 =新TranslateAnimation(0,0,DPY,0);
    b2.setDuration(320);
    b2.setFillAfter(真);    b1.setAnimationListener(新Animation.AnimationListener(){
        @覆盖
        公共无效onAnimationStart(动画动画){}        @覆盖
        公共无效onAnimationEnd(动画动画){
            footerButton.startAnimation(B2);
        }        @覆盖
        公共无效onAnimationRepeat(动画动画){}
    });    footerButton.startAnimation(B1);
}

PS:不要忘了在清单中使用 adjustResize 键,使内容(例如,在我的测试中edittexts)上方 alignParentBottom 为true。

页脚按钮

I have used android:windowSoftInputMode="adjustResize" in the manifest to prevent keyboard from hiding the activity button. It works, but when keyboard opens, my button moves up. It is a bit jumpy, I wanted to know - can I have any animation for that to transition smoothly?

<activity
        android:name=".Activity"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="adjustResize">
</activity>

解决方案

The method setSoftInputMode(int) cannot be overrided, its implementation is inside Window class and I don't think that's possible to replace the current window by your own. You cannot manage this from WindowManager too.
You could create a listener on a ViewGroup and catch the modification's layout when the SoftKeyboard is opening and closing. Indeed, when the SKB shows up, the container's layout redraws and changes its height. From this event, you could manage to set an Animation on views child and make a smooth effect.

Edit: The solution by using a GlobalLayoutListener on the rootview is also possible instead of (the solution presented below) creating a custom viewgroup class.

You have to create your own viewgroup and make it as a parent container in the layout. It'll implement an interface which will be handled in the UI class (Activity, Fragment, whatever). I found this blog to detect the events on SKB for (~)all versions. According to it, here's the viewgroup's class to handle the height's changes:

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);
    }
}

Now, you've to add this viewgroup in layout (eg <com.package.name.ContainerViewHandler .../>). Then, you must implement the above interface setKeyboardStateListener in the activity, like the following:

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!");
    }
});

Thus, you can manage different animations to handle and prevent the button to "jump" directly above the SKB. To test this out, I test by giving a bounce effect:

I begin by setting two animations (a1, a2) in the first callback:

  • a1: start below (behind) the SKB (about 4xbutton's height) and up to 20dp above it,
  • a2: start at 20dp and return to 0dp (normal position).

And two others (b1, b2) in the second callback:

  • b1: start where the button is up to 30dp at top and go down to 30dp outside the parent container,
  • b2: finaly, from 30dp out to `0dp (the initial position).

This how my implementation looks like:

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);
}

PS: don't forget to use adjustResize in the Manifest and to make the content (eg edittexts in my tests) above the footer button which has alignParentBottom to true.

这篇关于动画AdjustResize的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆