动画窗口布局更改

jdo*_*ell 6 android android-layout

我有一个DialogFragment,通常以屏幕为中心,我试图移开屏幕键盘,如果有任何应该出现,因为它不是一个良好的用户体验键盘覆盖部分窗口,当完全未使用的屏幕房地产更远.

假设我已经解决了检测键盘出现或消失的问题,例如如何检查Android中软件键盘的可见性?.

目前我通过做这样的事情来移开窗口:

...
final WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
params.gravity = Gravity.TOP;
params.verticalMargin = .1f;  //or whatever
dialog.getWindow().setAttributes(params);
...
Run Code Online (Sandbox Code Playgroud)

这很好用,但是窗口突然变成了一个位置,这不是一个愉快的用户体验.有问题的窗口有一个成功的进入和退出动画 - 这些甚至可以在窗口布局更改后正常工作.如何在WindowManager.LayoutParams更改之间进一步设置窗口动画?

(我希望在可能的情况下继续使用http://developer.android.com/reference/android/view/Window.html中的} {{}的布局,而不是强迫DialogFragment进入我的活动的布局并从那里制作动画.

jdo*_*ell 2

我没有时间等待赏金到期,所以我编写了下面的止损代码,直到我能得到更好的解决方案。如果它对其他人有帮助,或者给他们一个值得赏金的答案的想法,这就是我所做的。然而,我怀疑它的效率非常低,因为我假设它强制每个动画帧进行窗口重新布局,而不是仅仅在屏幕上平移位图。当然这不是全部,但却是关键的一点:

// Not shown: setting currentVerticalMargin, targetVerticalMargin, or calling this method
private synchronized void restartVerticalMarginAnimator() {
    if (verticalMarginAnimator != null) {
        return;
    }
    final Dialog dialog = this.getDialog();
    if (dialog == null) {
        return;
    }
    final WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
    verticalMarginAnimator = new TimeAnimator();
    verticalMarginAnimator.setTimeListener(new TimeListener() {
        @Override
        public void onTimeUpdate(TimeAnimator a, long totalTime, long deltaTime) {
            float stretch = targetVerticalMargin - currentVerticalMargin;
            float distance = WINDOW_ANIMATION_SPEED * deltaTime / 1000L;
            boolean finished = false;

            // Adjust distance so it's capped at "going all the way to target" and no further,
            // and has the right sign if we're animating upward.
            if (distance > Math.abs(stretch)) {
                distance = stretch;
                finished = true;
            } else if (stretch < 0) {
                distance *= -1f;
            }

            // Move.
            currentVerticalMargin += distance;
            if (finished) {
                verticalMarginAnimator.end();
                verticalMarginAnimator = null;
            }
            params.verticalMargin = currentVerticalMargin;
            dialog.getWindow().setAttributes(params);
        }
    });
    verticalMarginAnimator.start();
}
Run Code Online (Sandbox Code Playgroud)