Snackbar and other animations stopped working on some Android devices

匿名 (未验证) 提交于 2019-12-03 02:45:02

问题:

I have a very odd issue that I cannot figure out. I was not an issue until recently but I can't seem to revert back to prevent it. Also the other odd thing is it works on some devices and others it does not.

The issue is animations. One in particular is snack bar. The snackbar should animate up and down but it is not. it just shows then hides. check video below to see issue.

Video of issue

Here is the Android code to animate the snackbar in

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {         ViewCompat.setTranslationY(mView, mView.getHeight());         ViewCompat.animate(mView)                 .translationY(0f)                 .setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)                 .setDuration(ANIMATION_DURATION)                 .setListener(new ViewPropertyAnimatorListenerAdapter() {                     @Override                     public void onAnimationStart(View view) {                         mView.animateChildrenIn(ANIMATION_DURATION - ANIMATION_FADE_DURATION,                                 ANIMATION_FADE_DURATION);                     }                      @Override                     public void onAnimationEnd(View view) {                         onViewShown();                     }                 }).start();     } 

Its using ViewCompat for the v4 Library. I have other animations working in another activity working fine. Also the issue is not on just one activity its all of them. That makes me think its system wide somehow. But they all use different internal themes but all extend Theme.AppCompat.NoActionBar.

Here is my main layout

<android.support.design.widget.AppBarLayout     android:id="@+id/appbar"     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"     app:elevation="4dp">      <android.support.v7.widget.Toolbar         android:id="@+id/toolbar"         android:layout_width="match_parent"         android:layout_height="?attr/actionBarSize"         android:background="?attr/colorPrimary"         app:titleTextAppearance="@style/ToolbarTitle"         app:popupTheme="@style/ThemeOverlay.AppCompat.Light"         app:layout_scrollFlags="scroll|enterAlways|snap"/>      <android.support.design.widget.TabLayout         android:id="@+id/tabs"         android:layout_width="match_parent"         android:layout_height="wrap_content"         app:tabTextAppearance="@style/TabText"         app:tabMinWidth="@dimen/tab_minwidth"         app:tabMode="fixed"         app:tabGravity="fill"         app:layout_scrollFlags="enterAlways"/>   </android.support.design.widget.AppBarLayout>  <FrameLayout     android:id="@+id/content_frame"     android:layout_width="match_parent"     android:layout_height="match_parent"     app:layout_behavior="@string/appbar_scrolling_view_behavior" >      <android.support.v4.view.ViewPager         android:id="@+id/viewpager"         android:layout_width="match_parent"         android:layout_height="match_parent" />  </FrameLayout>  <fr.castorflex.android.circularprogressbar.CircularProgressBar     android:id="@+id/base_progressSpinner"     android:layout_gravity="center"     android:layout_width="48dp"     android:layout_height="48dp"     android:indeterminate="true"     android:visibility="invisible"     app:cpb_color="@color/spinner"     app:cpb_rotation_speed="1.0"     app:cpb_sweep_speed="1.0"     app:cpb_stroke_width="4dp"     app:cpb_min_sweep_angle="10"     app:cpb_max_sweep_angle="300"/>  <android.support.design.widget.FloatingActionButton     android:id="@+id/fab_upload"     android:visibility="gone"     android:layout_height="wrap_content"     android:layout_width="wrap_content"     app:layout_anchor="@id/content_frame"     app:layout_anchorGravity="bottom|right|end"     app:borderWidth="0dp"     android:src="@drawable/app_fab_upload"     android:layout_margin="@dimen/big_padding"     android:clickable="true"     app:backgroundTint="@color/fab_social"/>  <android.support.design.widget.FloatingActionButton     android:id="@+id/fab_muzei"     android:visibility="gone"     android:layout_height="wrap_content"     android:layout_width="wrap_content"     app:layout_anchor="@id/content_frame"     app:layout_anchorGravity="bottom|right|end"     app:borderWidth="0dp"     android:src="@drawable/app_fab_muzei"     android:layout_margin="@dimen/big_padding"     android:clickable="true"     app:backgroundTint="@color/fab_social"/>   </android.support.design.widget.CoordinatorLayout> 

Devices it works on

  • Nexus 9 (Marshmallow)
  • Nexus 4 (KitKat)
  • Galaxy S7 (Marshmallow)

Devices it does not work

  • Droid Turbo 2 (Marshmallow)
  • Galaxy S7 (Marshmallow) *my device works, my testers does not
  • Nexus 6p (Android N)

The other animation issues are with Switches. I have 2 in same layout and one stutters when switched and the other just switches with no animation.

I also have a LayoutTransition set to my AppBarLayout to animation the hiding/showing of my TabLayout and it works fine and all devices

回答1:

I found the reason why this is happening, but not how to fix yet.

/**  * Returns true if we should animate the Snackbar view in/out.  */ private boolean shouldAnimate() {     return !mAccessibilityManager.isEnabled(); } 

That is called by Snackbar class and is false on working devices, and true on devices not working. Does anyone know about this?

So after i disabled lastpass in my system settings, accessibility the snackbar now animates as it should. That is crazy how that works. Nova launcher has the same affect. I guess any service in accessibility that is enabled will cause the snackbar animation to not work.



回答2:

As Bignadad mentioned, the problem is that any accessibility feature, including things like password managers, disables the snackbar animations. Google, as of this writing, is still refusing to fix it

As I see it, because Snackbar's base class, BaseTransientBottomBar, handles the animation, with package private, final methods, you have two choices if you want to fix it: roll your own snackbar from scratch, or use a more hacky solution with reflection:

Kotlin example:

Snackbar.make(coordinatorLayout, text, duration).apply {         try {             val mAccessibilityManagerField = BaseTransientBottomBar::class.java.getDeclaredField("mAccessibilityManager")             mAccessibilityManagerField.isAccessible = true             val accessibilityManager = mAccessibilityManagerField.get(this)             val mIsEnabledField = AccessibilityManager::class.java.getDeclaredField("mIsEnabled")             mIsEnabledField.isAccessible = true             mIsEnabledField.setBoolean(accessibilityManager, false)             mAccessibilityManagerField.set(this, accessibilityManager)         } catch (e: Exception) {             Log.d("Snackbar", "Reflection error: $e")         }     } 

Java example:

Snackbar snackbar = Snackbar.make(coordinatorLayout, text, duration);     try {         Field mAccessibilityManagerField = BaseTransientBottomBar.class.getDeclaredField("mAccessibilityManager");         mAccessibilityManagerField.setAccessible(true);         AccessibilityManager accessibilityManager = (AccessibilityManager) mAccessibilityManagerField.get(snackbar);         Field mIsEnabledField = AccessibilityManager.class.getDeclaredField("mIsEnabled");         mIsEnabledField.setAccessible(true);         mIsEnabledField.setBoolean(accessibilityManager, false);         mAccessibilityManagerField.set(snackbar, accessibilityManager);     } catch (Exception e) {         Log.d("Snackbar", "Reflection error: " + e.toString());     }     return snackbar; 

I'd love a third option here, but I'm not aware of one. I recommend anyone else experiencing this bug complain loudly.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!