활동 장면 애니메이션 전환 중에 상태 표시 줄과 탐색 표시 줄에 애니메이션이 표시되지 않도록하려면 어떻게합니까?


127

먼저 내 상태 표시 줄 배경이 짙은 갈색으로 설정되어 있고 내비게이션 바 배경이 기본적으로 검은 색입니다. 머티리얼 라이트 테마를 사용하고 있습니다.

ActivityOptions.makeSceneTransitionAnimation기본 전환을 사용하여 새 활동을 시작하고 있는데 상태 표시 줄과 탐색 표시 줄이 잠시 흰색으로 바뀐 다음 올바른 색상으로 되돌아 오는 것을 알 수 있습니다.

설명서 에 따르면 :

전환 효과를 최대한 활용하려면 호출 및 호출 된 활동 모두에서 창 내용 전환을 활성화해야합니다. 그렇지 않으면 호출 활동이 종료 전환을 시작하지만 창 전환 (스케일 또는 페이드와 같은)이 표시됩니다.

나는 getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);부름과 부름 활동을 모두 사용 하고 있습니다.

마찬가지로 입력 전환을 슬라이드로 변경하면 상태 표시 줄과 탐색 표시 줄에 흰색 배경의 슬라이드 전환이 잠깐 있습니다.

활동 장면 애니메이션 전환 중에 상태 표시 줄과 탐색 표시 줄에 애니메이션이 표시되지 않도록하려면 어떻게합니까?

답변:


217

전환 중에 탐색 / 상태 표시 줄에 애니메이션이 표시되는 것을 방지하기 위해 사용할 수있는 두 가지 방법이 있습니다.

접근법 # 1 : 창의 기본 종료 / 입력 페이드 전환에서 상태 표시 줄 및 탐색 표시 줄을 제외

전환 중에 탐색 / 상태 표시 줄이 페이드 인 및 페이드 아웃되는 이유는 기본적으로 전환이 시작되면 공유되지 않은 모든보기 (탐색 / 상태 표시 줄 배경 포함)가 호출 / 활동에서 각각 페이드 아웃 / 인되기 때문입니다. . 그러나 창의 기본 종료 / 입력 Fade전환 에서 탐색 / 상태 표시 줄 배경을 제외하면이 문제를 쉽게 해결할 수 있습니다 . 액티비티 onCreate()메소드에 다음 코드를 추가하기 만하면됩니다 .

Transition fade = new Fade();
fade.excludeTarget(android.R.id.statusBarBackground, true);
fade.excludeTarget(android.R.id.navigationBarBackground, true);
getWindow().setExitTransition(fade);
getWindow().setEnterTransition(fade);

이 전환은 XML을 사용하여 활동 주제 (예 res/transition/window_fade.xml: 자신의 파일) 에서 선언 할 수도 있습니다 .

<?xml version="1.0" encoding="utf-8"?>
<fade xmlns:android="http://schemas.android.com/apk/res/android">
    <targets>
        <target android:excludeId="@android:id/statusBarBackground"/>
        <target android:excludeId="@android:id/navigationBarBackground"/>
    </targets>
</fade>

접근 # 2 : 상태 표시 줄 및 탐색 표시 줄을 공유 요소로 추가

이 방법은 klmprt의 대답의 오프 빌드 거의 나는 아직도 수정의 몇 가지를 만드는 데 필요한 있지만 ... 날 위해 일했습니다.

내 호출 활동에서 다음 코드를 사용하여 활동을 시작했습니다.

View statusBar = findViewById(android.R.id.statusBarBackground);
View navigationBar = findViewById(android.R.id.navigationBarBackground);

List<Pair<View, String>> pairs = new ArrayList<>();
if (statusBar != null) {
  pairs.add(Pair.create(statusBar, Window.STATUS_BAR_BACKGROUND_TRANSITION_NAME));
}
if (navigationBar != null) {
  pairs.add(Pair.create(navigationBar, Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME));
}
pairs.add(Pair.create(mSharedElement, mSharedElement.getTransitionName()));

Bundle options = ActivityOptions.makeSceneTransitionAnimation(activity, 
        pairs.toArray(new Pair[pairs.size()])).toBundle();
startActivity(new Intent(context, NextActivity.class), options);

지금까지 이것은 klmprt가 그의 대답에서 제안한 것과 본질적으로 동일합니다. 그러나 onCreate()전환 중에 상태 표시 줄과 탐색 표시 줄이 "깜박이는"것을 방지하기 위해 호출 된 활동의 메소드에 다음 코드를 추가해야했습니다 .

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

    // Postpone the transition until the window's decor view has
    // finished its layout.
    postponeEnterTransition();

    final View decor = getWindow().getDecorView();
    decor.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {
            decor.getViewTreeObserver().removeOnPreDrawListener(this);
            startPostponedEnterTransition();
            return true;
        }
    });
}

상태 표시 줄과 탐색 표시 줄 배경을 공유 요소로 추가하면 창의 기본 종료 / 입력 페이드 전환 위에 강제로 그려 지므로 전환 중에 페이드되지 않습니다. 이 방법에 대한 자세한 내용은 이 Google+ 게시물 에서 확인할 수 있습니다 .


14
Lollipop에서 findViewById (android.R.id.navigationBarBackground)가 null을 반환하는 이유는 무엇입니까? appcompat-v7
radzio를 사용하고 있습니다.

3
접근법 # 2는 작동하지만 전환이 발생할 때 여전히 액티비티가 깜박입니다. 상태 표시 줄과 탐색 표시 줄이 더 이상 깜박이지 않습니다.
Akshat

16
@ 알렉스 우리가 함께 새로운 지원 라이브러리로 전환 할 때까지 나를 위해 거의 완벽하게 작동 android.support.design.widget.TabLayoutandroid.support.design.widget.AppBarLayout - 지금 깜빡가 돌아왔다
노아 DRACH

6
android.R.id.navigationBarBackground는 화면 내비게이션 바가 없으므로 Samsung 또는 HTC 기기에서 NPE를 제공 할 수 있습니다. 공유 요소로 추가하기 전에 null 검사를 수행하십시오
Boy

8
안드로이드 누가와 넥서스 6 에서이 솔루션을 시도하고 있습니다. 그러나 두 가지 접근 방식이 모두 효과가 없습니다.
Pardeep Kr

4

활동 전환이 공유 요소 전환을 방해하는 것을 완전히 방지하십시오.

종료 활동에서 getWindow (). setExitTransition (null);

입력 활동에서 getWindow (). setEnterTransition (null);

에서 https://stackoverflow.com/a/34907685/967131

부작용이 있을지 모르지만 확실하지 않습니다. 그것은 간단하지만 죽었습니다.

특정 요소가 깜박이는 것을 방지하십시오.

나는 Alex Lockwood의 답변으로 시작하여 작동시키기 위해 약간의 실험을했습니다. 수신 활동에 대해 제안하는 코드가 필요하지 않지만 핵심은 정확하지만 조각 대신 (활동 대신) 조각을 호출하고 도구 모음을 작업 표시 줄로 설정하여 문제가 발생했습니다.

오, 조각 이요? 상태 표시 줄과 탐색 표시 줄에 대한 참조를 검색하려고 시도하는 것이 null이라는 많은 의견을 보았습니다. 조각의 레이아웃에서 그것들을 찾을 수 없다는 것을 깨달을 때까지 나에게도 같은 일이 일어났습니다. 따라서 아래 코드는 활동에서 장식보기를 가져 와서 검색합니다. 그런 다음 아무런 문제없이 발견했습니다.

결국, 나는이 유틸리티 방법을 개발했습니다 :

public static Bundle transitionOptions(Activity activity, int transitionViewResId, int transitionNameResId) {
   if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
       return null;
   }

   View decorView = activity.getWindow().getDecorView();
   View statusBar = decorView.findViewById(android.R.id.statusBarBackground);
   View navigationBar = decorView.findViewById(android.R.id.navigationBarBackground);
   View appBarLayout = decorView.findViewById(**R.id.appbarlayout**);
   View transitionView = decorView.findViewById(transitionViewResId);
   String transitionName = activity.getString(transitionNameResId);

   List<Pair<View, String>> pairs = new ArrayList<>();
   pairs.add(Pair.create(statusBar, Window.STATUS_BAR_BACKGROUND_TRANSITION_NAME));
   pairs.add(Pair.create(navigationBar, Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME));
   if (appBarLayout != null) {
       pairs.add(Pair.create(appBarLayout, activity.getString(**R.string.transition_appbarlayout**)));
   }
   pairs.add(Pair.create(transitionView, transitionName));
   //noinspection unchecked - we're not worried about the "unchecked" conversion of List<Pair> to Pair[] here
   return ActivityOptionsCompat.makeSceneTransitionAnimation(activity, pairs.toArray(new Pair[pairs.size()]))
           .toBundle();
}

R.string.transition_appbarlayoutR.id.appbarlayout을 참고하십시오 . 이 ID는 코드가 사용하는 것과 일치하는 한 임의적입니다. 내 XML에서 사용자 정의 작업 표시 줄을 다음과 같이 레이아웃합니다 (필수 사항까지 편집).

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
    android:id="**@+id/appbarlayout**"
    android:transitionName="**@string/transition_appbarlayout**">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"/>
</android.support.design.widget.AppBarLayout>

이와 같은 툴바를 사용하지 않으면 유틸리티 부분에서 해당 부분을 제거 할 수 있습니다.

그런 다음 조각에서 다음과 같이 호출합니다.

startActivity(intent, UIUtils.transitionOptions(getActivity(),
                        R.id.**my_view**,
                        R.string.**transition_my_view**));

XML과 일치하는 한 원하는 값을 사용하십시오.

그러면 전환 중에 상태 표시 줄, 도구 모음 및 탐색 모음 (뒤로 / 홈 / 최근 앱 버튼)이 깜박이지 않습니다. 나머지 활동 전환은 정상입니다.

필자의 경우 앱 테마는 android:windowBackground파란색입니다. 이로 인해 전환시 파란색 깜박임이 발생하여 매우 실망 스러웠습니다. 그러나 전체 앱에 영향을 미치는 변경을하기보다는 지금은 빠르고 더러운 옵션을 사용합니다.


3

당신은 그들을 공유해야합니다 ActivityOptions.makeSceneTransitionAnimation.

예 :

ActivityOptions.makeSceneTransitionAnimation(... Pair.create(activity.findViewById(android.R.id.window_status_bar), Window.STATUS_BAR_BACKGROUND_TRANSITION_NAME) 

(의사 실례합니다; 정확한 android.R.id 값이 없습니다)

뷰를 공유 한 후 적절한 전환을 실행할 수 있습니다.


이것이 당신을 위해 일했습니까? 나는 이것을 시도하고 전환하는 동안 상태 표시 줄과 탐색 표시 줄이 여전히 흰색으로 깜박입니다.
rlay3

예, 그것은 나를 위해 일했습니다. 일시적으로 겹칠 수있는 다른 뷰가 없습니까? '샌드 박스형'환경에서 간단한 활동 전환을 설정하여 문제를 분리하려고 했습니까?
klmprt

@klmprt 입력 전환을 연기하기 위해 연기를 연기해야한다고 생각합니다 ...보기를 공유하여 상태 / 탐색 막대가 애니메이션으로 표시되는 것을 막을 수 없었습니다. 입력 전환이 시작되기 전에 창의 장식보기가 레이아웃을 완료 할 때까지 기다려야한다고 생각합니다.
Alex Lockwood

@klmprt 그래도 여전히 해결하지 못하는 것은 전환 중에 작업 표시 줄의 배경색이 애니메이션되는 것을 방지하는 방법입니다. 두 활동 모두 동일한 작업 표시 줄 배경색을 공유하는 경우, 호출 활동의 작업 표시 줄이 점차 사라지고 호출 된 활동의 작업 표시 줄이 부드럽게 사라짐에 따라 작업 표시 줄의 배경색이 애니메이션으로 나타납니다.이 문제를 해결하는 방법이 있습니까? 발행물?
Alex Lockwood

@klmprt 사실, 더 나은 해결책이 있다고 생각합니다. 창의 기본 종료 / 입력 페이드 전환에서 탐색 / 상태 표시 줄 배경을 대상으로 간단히 제외 할 수 있습니다. 자세한 내용은 업데이트 된 답변을 참조하십시오.
Alex Lockwood

3

내가 이해하는 한 이것은 활동 전환 겹침으로 인해 발생합니다. 이 문제를 극복하기 위해 onCreate()두 가지 방법 모두 에서 다음 값을 사용했습니다 .

getWindow().setAllowEnterTransitionOverlap(false);
getWindow().setAllowReturnTransitionOverlap(false);

3

방금이 같은 문제가 있었고 대답은 퍼즐의 중요한 부분이 누락 된 것으로 보입니다. 공유 요소 전환에서는 모든 것이 대상 활동 에서 발생합니다 .

깜박임 효과를 제거하려면 호출중인 활동에 다음을 추가하십시오.

Fade fade = new Fade();
fade.excludeTarget(android.R.id.statusBarBackground, true);
fade.excludeTarget(android.R.id.navigationBarBackground, true);

getWindow().setEnterTransition(fade);
getWindow().setExitTransition(fade);

문제가 해결 될 것입니다!


안녕하세요. 이것은 최상위 답변의 접근법 # 1과 동일하지 않습니까?
rlay3

@ rlay3 전부는 아닙니다. 내가 알 수있는 한, 그는 목적지 활동에서만 설정해야한다는 사실을 언급하지 않았습니다.
LukeWaggoner

안녕하세요 @LukeWaggoner 도와주세요 : stackoverflow.com/questions/50189286/…
blackHawk

활동자, 발신자 및 수신자 모두에서 상태 표시 줄과 탐색 표시 줄을 제외해야합니다.
Giovanni Di Gregorio


0

내가 한 방법은 다음과 같습니다. 나는 다음 과 함께 Status Bar와를 공유 합니다 .Navigation BarSharedElementTransitionImageView

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  View imageView = view.findViewById(R.id.iv);
  Resources resources = view.getResources();
  imageView.setTransitionName(resources.getString(R.string.transition_image_thumbnail));

  Pair<View, String> p1 = Pair.create(imageView, resources.getString(R.string.transition_image_thumbnail));

  Window window = getActivity().getWindow();

  View navigationBar = getActivity().findViewById(android.R.id.navigationBarBackground);
  View statusBar = getActivity().findViewById(android.R.id.statusBarBackground);

  Pair<View, String> p2 = Pair.create(statusBar, statusBar.getTransitionName());
  Pair<View, String> p3 = Pair.create(navigationBar, navigationBar.getTransitionName());

  ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(),
          p1, p2, p3);

  ActivityCompat.startActivity(getActivity(), intent, options.toBundle());
} else {
  startActivity(intent);
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.