Android googleMap - как запустить две анимации обновления камеры? - PullRequest
1 голос
/ 03 мая 2019

У меня есть две анимации, которые я хочу выполнить на карте Google в последовательности. Поэтому после завершения анимации 1 анимация 2 может двигаться дальше.

это можно легко сделать с помощью обратного вызова:

 googleMap.animateCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), horizontalBounds, verticalBounds, 8), object : GoogleMap.CancelableCallback {
        override fun onCancel() {
            animationCompletionBlock()
        }

        override fun onFinish() {
            //start the second animation
            googleMap.animateCamera(CameraUpdateFactory.zoomTo(16f), object : GoogleMap.CancelableCallback {
                override fun onFinish() {
                }

                override fun onCancel() {
                }

            })

мой вопрос о качестве кода, я думаю, чистота. Я хочу знать, есть ли более простой или лучший способ последовательности анимации. Например, есть способ предоставить массив обновлений камеры для последовательного запуска с помощью API Google ... выглядит ужасно, когда нужно вызывать другую анимацию внутри onFinish для первой анимации камеры. Обратные вызовы выглядят некрасиво, немного пахнут. Есть ли способ проектирования шаблона или построения таким образом, чтобы он выглядел лучше?

1 Ответ

2 голосов
/ 15 мая 2019

В Google Maps есть только один способ сделать последовательность анимации: запустить следующую анимацию в onFinish() предыдущей.Но в любом случае, вы можете реализовать свой собственный путь для этого.Например, что-то в этом роде, на основе Медиатор и Цепочка ответственности шаблонов:

public class CameraAnimationManager implements GoogleMap.CancelableCallback {

    private GoogleMap mGoogleMap;
    private List<CameraAnimation> mAnimations = new ArrayList<>();   // list of "animations"
    private int mCurrentAnimationIndex = -1;                         // index of current animation


    public CameraAnimationManager(GoogleMap googleMap) {
        mGoogleMap = googleMap;
    }


    @Override
    public void onFinish() {
        // if next animation exists
        if (mCurrentAnimationIndex < mAnimations.size() - 1) {
            // animate it
            mCurrentAnimationIndex++;
            CameraAnimation currentAnimation = mAnimations.get(mCurrentAnimationIndex);
            animate(currentAnimation);
        } else {
            mCurrentAnimationIndex = -1;
        }
    }


    @Override
    public void onCancel() {
        stopAnimation();
        mCurrentAnimationIndex = -1;
    }


    private void animate(CameraAnimation currentAnimation) {
        mGoogleMap.animateCamera(currentAnimation.cameraUpdate, currentAnimation.duration, this);
    }


    public void clear() {
        stopAnimation();
        mAnimations.clear();
        mCurrentAnimationIndex = -1;
    }


    public void addAnimation(CameraAnimation animation) {
        mAnimations.add(animation);
    }

    public void startAnimation() {
        // start sequence of animations from first
        if (mAnimations.size() > 0) {
            mCurrentAnimationIndex = 0;
            CameraAnimation currentAnimation = mAnimations.get(mCurrentAnimationIndex);
            animate(currentAnimation);
        }
    }


    public void stopAnimation() {
        mGoogleMap.stopAnimation();
    }


    // class for animation parameters store
    static class CameraAnimation {
        public CameraUpdate cameraUpdate;
        public int duration;


        public CameraAnimation(CameraUpdate cameraUpdate, int duration) {
            this.cameraUpdate = cameraUpdate;
            this.duration = duration;
        }
    }

}

CameraAnimationManager объект реализует GoogleMap.CancelableCallback и обрабатывает onFinish(),В этом случае новая анимация начинается не непосредственно с onFinish() предыдущей анимации, а с onFinish() из CameraAnimationManager, и вы можете более гибко управлять последовательностью анимации (каждая анимация не хранит информацию о следующей анимации, и вы можете изменить анимациюзаказ в CameraAnimationManager.mAnimations).

И вы можете назвать это так:

...
@Override
public void onMapReady(GoogleMap googleMap) {
    mGoogleMap = googleMap;
    mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(13.807303, 100.518261), 16));
}
...

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mMapFragment = (MapFragment) getFragmentManager()
            .findFragmentById(R.id.map_fragment);
    mMapFragment.getMapAsync(this);

    mStartAnimationSequenceButton= (Button) findViewById(R.id.button_start_animation);
    mStartAnimationSequenceButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mGoogleMap != null) {
                CameraUpdate location1 = CameraUpdateFactory.newLatLngZoom(new LatLng(13.747871, 100.488370), 16);
                CameraUpdate location2 = CameraUpdateFactory.newLatLngZoom(new LatLng(13.726253, 100.512301), 16);
                CameraUpdate location3 = CameraUpdateFactory.newLatLngZoom(new LatLng(13.692890, 100.490688), 16);

                mAnimationManager = new CameraAnimationManager(mGoogleMap);
                mAnimationManager.addAnimation(new CameraAnimationManager.CameraAnimation(location1, 3000) );
                mAnimationManager.addAnimation(new CameraAnimationManager.CameraAnimation(location2, 3000) );
                mAnimationManager.addAnimation(new CameraAnimationManager.CameraAnimation(location3, 3000) );
                mAnimationManager.startAnimation();
            }
        }
    });
}

для короткой поездки по реке Чао Прайя ...

...