본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[android] Shared Element Transition Tutorial ( with transparent bg )

by 돼지왕 왕돼지 2018. 9. 28.
반응형

[android] Shared Element Transition Tutorial ( with transparent bg )


https://medium.com/@aitorvs/android-shared-element-transitions-for-all-b90e9361507d#.zoz5i6xkz

Android, animation, compat, material activity transition, onpredraw, shared element transition, shared element transition tutorial, Theme, transparent bg, view info, [android] Shared Element Transition Tutorial ( with transparent bg )


-

LOS 이상부터는 이를 구현하는 것이 매우 쉽다.

https://developer.android.com/training/transitions/start-activity )

그러나 그 이전버전도 지원하는 경우 버전분기를 하는 공수가 든다.

그래서 새로운 API 없이 Compat 한 방법으로 Transition 하는 방법을 소개한다.



-

Activity A -> B 로 이동시 동일한 모양을 가진 View 가 있다면,

A 에 있는 View 가 B 로 자연스럽게 translate, resize 되는 것이 좋아 보인다.

이를 통해 중요한 정보가 무엇인지와, 연속성을 줄 수 있다.



-

방법은..


1. Activity A 가 shared element 에 대한 정보를 Activity B 에게 intent 를 통해 전달한다.

2. Activity B 가 투명 상태로 시작한다.

3. Activity B 가 bundled values 를 읽고 scene 을 준비한다.

4. Actrvity B 가 shared element animation 을 진행한다.



-

shared element 정보 전달

// psudo

… {

Intent intent = new Intent( … );

intent.putExtra(KEY_SHARED_VIEW_INFO, captureValues(originalView));

startActivity(intent);

overridePendingTransition(0, 0); // key code!!

}


private Bundle captureValues (View view){

Bundle  b = new Bundle();

int[] screenLocation = new int[2];

view.getLocationOnScreen(screenLocation);

b.putInt(LEFT, screenLocation[0]);

b.putInt(TOP, screenLocation[1]);

// width, height 정보도 bundle 에 심어야 한다.

}



-

activity B 를 투명상태로 시작..

<style name="Transparent" parent="AppTheme">

        <item name="android:windowIsTranslucent">true</item>

        <item name="android:windowBackground">@android:color/transparent</item>

</style>

위와 같은 투명 style 을 activity B 에 적용한다.



-

Activity B 에서 scene 을 준비시킨다.


layout 후, drawing 전에 불리는 callback 은 onPreDraw() 이다.

mDestinationView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {

            @Override

            public boolean onPreDraw() {

                mDestinationView.getViewTreeObserver().removeOnPreDrawListener(this);

                prepareScene();

                runEnterAnimation();

                return true;

            }

});


private void prepareScene() {

        mEndValues = captureValues(mDestinationView); // bundle


        // calculate the scale and positoin deltas

        float scaleX = scaleDelta(mStartValues, mEndValues);

        float scaleY = scaleDelta(mStartValues, mEndValues);

        int deltaX = translationDelta(mStartValues, mEndValues);

        int deltaY = translationDelta(mStartValues, mEndValues);


        // scale and reposition the image

        mDestinationView.setScaleX(scaleX);

        mDestinationView.setScaleY(scaleY);

        mDestinationView.setTranslationX(deltaX);

        mDestinationView.setTranslationY(deltaY);

}




-

animation 을 수행한다.

private void runEnterAnimation() {

        mDestinationView.setVisibility(View.VISIBLE);

        mDestinationView.animate()

                .setDuration(DEFAULT_DURATION)

                .setInterpolator(DEFAULT_INTERPOLATOR)

                .scaleX(1f)

                .scaleY(1f)

                .translationX(0)

                .translationY(0)

                .start();

}



-

Activity Theme 중 아래의 설정 때문에 paused 되지만 stopped 되지 않는다.

이 점에 유의해야 한다.

<item name=”android:windowIsTranslucent”>true</item> 



-




반응형

댓글