FloatingActionButtonSpeedDial icon indicating copy to clipboard operation
FloatingActionButtonSpeedDial copied to clipboard

Calling hide() and show() causes sdMainFabClosedSrc and sdMainFabOpenSrc disappear. (support lib 28.0.0)

Open naco-siren opened this issue 6 years ago • 14 comments

Step 1: Are you in the right place?

  • [x] I have verified there are no duplicate active or recent bugs, questions, or requests
  • [x] I have verified that I am using the latest version of the library.

Step 2: Describe your environment

  • Library version: 1.0.2
  • Android version: 27
  • Support library version: 28.0.0-alpha3
  • Device brand: Google
  • Device model: Pixel XL

Step 3: Describe the problem:

Steps to reproduce:

  1. call hide() to hide the SpeedDialView.
  2. call show() to show it.
  3. click on the SpeedDialView to open the menu, observe that A.
  4. click on the SpeedDialView's main fab to close the menu, observe that B.

Observed Results:

  • A. the main fab's open icon is gone.
  • B. the main fab's closed icon is also gone.

Expected Results:

  • the main fab's open icon should be visible.
  • the main fab's closed icon should be visible.

Screenshots:

bug - open icon bug - close icon

Notice that the menu's smaller fabs do have the icon correctly set.

naco-siren avatar Jul 13 '18 06:07 naco-siren

Also, main fab's ripple effect always triggers from top-left corner instead of the touch point.

naco-siren avatar Jul 13 '18 06:07 naco-siren

Hi @naco-siren, I started investigating this issue and it seems to happen only with the support library version 28.0.0-alpha3 (27.1.1 still works fine).

Until I find a better solution my suggestion is to use the latest stable version.

leinardi avatar Jul 13 '18 08:07 leinardi

I have reported the bug in the issuetracker of the support libraries. Please consider starring the issue for visibility (and if you want to get updates): https://issuetracker.google.com/issues/111433526

leinardi avatar Jul 14 '18 09:07 leinardi

@naco-siren I experienced this issue as well on android support version '28.0.0-rc01'. As for temporary solution, I use view.setVisibilty(View.INVISIBLE) to hide fab view, but it cost me to lose the animation.

panjiyudasetya avatar Sep 14 '18 09:09 panjiyudasetya

Hi @naco-siren, if you want to keep the animation you can try this other workaround:

/**
 * Workaround class for https://issuetracker.google.com/issues/111316656 is released.
 * If you call [showWithWorkaround] manually you should also hide the [SpeedDialView]
 */
class ScrollingViewSnackbarBehaviorWithWorkaround : SpeedDialView.ScrollingViewSnackbarBehavior {
    constructor()
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)

    override fun show(child: View) {
        when (child) {
            is FloatingActionButton -> showWithWorkaround(child)
            is SpeedDialView -> {
                showWithWorkaround(child.mainFab)
                child.visibility = View.VISIBLE
            }
            else -> child.visibility = View.VISIBLE
        }
    }

    companion object {
        @JvmStatic
        fun showWithWorkaround(fab: FloatingActionButton) {
            fab.show(object : FloatingActionButton.OnVisibilityChangedListener() {
                override fun onShown(fab: FloatingActionButton) {
                    val impl = fab::class.java.getDeclaredField("impl").let {
                        it.isAccessible = true
                        it.get(fab)
                    }

                    val implClass = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        impl::class.java.superclass
                    } else {
                        impl::class.java
                    }

                    val scale =
                        implClass.getDeclaredMethod("setImageMatrixScale", Float::class.java)
                    scale.isAccessible = true
                    scale.invoke(impl, 1.0F)
                }
            })
        }
    }
}

You just need to use this Behavior instead of the SpeedDialView.ScrollingViewSnackbarBehavior. If you want to show the FAB manually just call the static method showWithWorkaround() and then manually set the visibility of the SpeedDialView to VISIBLE (the normal hide() can still be used).

leinardi avatar Sep 14 '18 09:09 leinardi

Google release v28 of the support libraries without fixing this issue. Unbelievable.

I implemented a workaround, it will be merged to the next release of this library.

EDIT The new version with the workaround is now live: https://github.com/leinardi/FloatingActionButtonSpeedDial/releases/tag/2.0.0

leinardi avatar Sep 23 '18 13:09 leinardi

This issue has been automatically marked as stale because it has not had activity in the last 60 days.

stale[bot] avatar Nov 25 '18 11:11 stale[bot]

This issue has come if i was create a build with progurad without progurad its working fine .So any progurad rule is required for that issue????

ImranHusain avatar Dec 10 '18 14:12 ImranHusain

Are you getting any of these errors?

                } catch (NoSuchMethodException e) {
                    Log.e(TAG, "Method setImageMatrixScale not found", e);
                } catch (IllegalAccessException e) {
                    Log.e(TAG, "IllegalAccessException", e);
                } catch (InvocationTargetException e) {
                    Log.e(TAG, "InvocationTargetException", e);
                } catch (NoSuchFieldException e) {
                    Log.e(TAG, "Field impl not found", e);
                }

leinardi avatar Dec 10 '18 14:12 leinardi

yes you are correct i am getting below error: E/SpeedDialView: Field impl not found java.lang.NoSuchFieldException: impl at java.lang.Class.getDeclaredField(Class.java:890) at xxx.SpeedDialView$2.d(Unknown Source) at android.support.design.widget.FloatingActionButton$1.cY(Unknown Source) at android.support.design.widget.h$2.onAnimationEnd(Unknown Source) at android.animation.AnimatorSet$AnimatorSetListener.onAnimationEnd(AnimatorSet.java:854) at android.animation.ValueAnimator.endAnimation(ValueAnimator.java:1171) at android.animation.ValueAnimator$AnimationHandler.doAnimationFrame(ValueAnimator.java:722) at android.animation.ValueAnimator$AnimationHandler.run(ValueAnimator.java:738) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) at android.view.Choreographer.doCallbacks(Choreographer.java:580) at android.view.Choreographer.doFrame(Choreographer.java:549) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5343) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)

ImranHusain avatar Dec 11 '18 05:12 ImranHusain

The rule is already provided by the library and is working on release builds afaik: https://github.com/leinardi/FloatingActionButtonSpeedDial/blob/9c2f5ed71c861536f38fcc98e1d8e3110c2b252f/library/consumer-proguard-rules.pro#L27

Are you using AndroidX and the enableJetifier option? If yes probably you have to update the rule for AndroidX.

Please let me know if that fixes the issue so that I can update the library proguard rules.

leinardi avatar Dec 11 '18 07:12 leinardi

Thanks leinardi lib proguard rule resolve my issue -keepclassmembernames class android.support.design.widget.FloatingActionButton { android.support.design.widget.FloatingActionButtonImpl impl; } -keepclassmembernames class android.support.design.widget.FloatingActionButtonImpl { void setImageMatrixScale(float); } No i am not using AndoridX.

ImranHusain avatar Dec 11 '18 09:12 ImranHusain

Mmm this is strange, the rule should be already provided with the library. Anyone else is experiencing the same issue?

leinardi avatar Dec 11 '18 09:12 leinardi

This issue has been automatically marked as stale because it has not had activity in the last 60 days.

stale[bot] avatar Feb 09 '19 09:02 stale[bot]