1

画面の上 1/3 を占める MapFragment と、画面の下 2/3 を占める ListView を持つビューを作成しました。ListView には、ユーザーが ListView 全体を上下にドラッグするために使用できるリスト項目のすぐ上に「ハンドル」があります。ユーザーが画面から指を離すと、ListView は画面全体のクローゼットの上または下の境界線にアニメーション化されます。これまでのところ動作していますが、アニメーションはスムーズではありません。ユーザーが画面から指を離した後、ListView が最も近い端に向かってアニメーションを開始する前に、顕著な一時停止があります。アニメーションがハニカム以前のデバイスで動作するように、ObjectAnimator の nineoldandroids 実装を使用しています。何か案は?

以下は私の onTouch impl です。

public boolean onTouch(View v, MotionEvent event) {
    final LayoutParams listLp = (LayoutParams) mListFrame.getLayoutParams();
    final int topMargin = -mHandleShadow.getHeight();
    final int middleMargin = getResources().getDimensionPixelSize(R.dimen.map_handle_margin_top);
    final int bottomMargin = getView().getHeight() - mHandle.getHeight() - mHandleShadow.getHeight();

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            mInitY = (int) event.getRawY();
            mTopMargin = listLp.topMargin;

            break;
        case MotionEvent.ACTION_MOVE:
            int y = mTopMargin + (int) event.getRawY() - mInitY;

            if (y >= -mHandleShadow.getHeight() && y <= (mViewHeight - mHandle.getHeight() - mHandleShadow.getHeight())) {
                listLp.topMargin = y;
                mListFrame.setLayoutParams(listLp);
            }

            break;
        case MotionEvent.ACTION_UP:
            if ((mInitY > event.getRawY() && mClosestAnchor == Anchor.MIDDLE) || (listLp.topMargin < middleMargin && mClosestAnchor == Anchor.BOTTOM)) {
                ObjectAnimator animator = ObjectAnimator.ofInt(AnimatorProxy.wrap(mListFrame), "topMargin", topMargin);
                animator.setInterpolator(new AccelerateInterpolator());
                animator.start();

                mClosestAnchor = Anchor.TOP;
            }
            else if ((mInitY < event.getRawY() && mClosestAnchor == Anchor.MIDDLE) || (listLp.topMargin > middleMargin && mClosestAnchor == Anchor.TOP)) {
                ObjectAnimator animator = ObjectAnimator.ofInt(AnimatorProxy.wrap(mListFrame), "topMargin", bottomMargin);
                animator.setInterpolator(new AccelerateInterpolator());
                animator.start();

                mClosestAnchor = Anchor.BOTTOM;
            }
            else {
                ObjectAnimator animator = ObjectAnimator.ofInt(AnimatorProxy.wrap(mListFrame), "topMargin", middleMargin);
                animator.setInterpolator(new AccelerateInterpolator());
                animator.start();

                mClosestAnchor = Anchor.MIDDLE;
            }

            break;
    }

    return true;
}
4

1 に答える 1

8

ここにある同様の質問に対する Google の Chet Haase の回答を読んだ後、最終的に問題を修正しました。https://stackoverflow.com/a/14780019/476005

フレームごとにビューのマージンを調整するのはコストがかかりすぎて、移動しているビューが非常に単純でない限り、常に途切れます。これを修正するために、OnTouch(...) メソッドで次のことを行います。

  1. On MotionEvent.ACTION_DOWN: ビューの高さを最大の高さに設定します。
  2. MotionEvent.ACTION_MOVE の場合: View の「y」プロパティを、期間が 0 の event.getRawY にアニメーション化します。
  3. On MotionEvent.ACTION_UP: ビューの「y」プロパティをビューの親の端の 1 つにアニメーション化します。ここで重要なことは、onAnimationEnd でビューの高さを適切に設定することです。

これがすべての人に役立つことを願っています。

于 2013-04-19T11:24:45.457 に答える