-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Slider] label is gone with slider #4320
[Slider] label is gone with slider #4320
Conversation
Thanks @manabu-nakamura, can you explain what you mean by your comment about performance? What is that code snippet from? |
The isVisible() method is an alternative to the isVisible field (and the onVisibilityAggregated() method). These are what I wrote. The isVisible field (and the onVisibilityAggregated() method) is more lightweight than the isVisible() method, I think. |
@@ -354,6 +354,8 @@ abstract class BaseSlider< | |||
private final ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = | |||
this::updateLabels; | |||
|
|||
private boolean isVisible = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@manabu-nakamura just wondering about the default value being true here. if the Slider visibility is set to gone
or invisible
initially (e.g. in the xml layout), will onVisibilityAggregated() be called with false immediately after the view is inflated / created?
if not then maybe in the constructor we could set isVisible = getVisibility() == View.VISIBLE
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just checked locally and onVisibilityAggregated
doesn't seem to get called when the Slider itself has android:visibility="invisible"
or android:visibility="gone"
in the XML layout.
So the isVisible
boolean would be incorrect in those cases, which makes me think we should not initialize isVisible
to true and instead do isVisible = getVisibility() == View.VISIBLE
in the constructor.
Although that doesn't cover the case where the Slider is visible
but the parent view is gone
. because in that case getVisibility() == View.VISIBLE
would return true in the Slider constructor and onVisibilityAggregated
doesn't get called after the initial inflation to correct it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much. Following pubiqq's advice, I replaced the isVisible field with the isShown() method. I tried displaying labels in the SliderScrollContainerDemoFragment demo. There seems to be no problem.
https://github.com/material-components/material-components-android/blob/master/catalog/java/io/material/catalog/slider/SliderScrollContainerDemoFragment.java
slider.setLabelBehavior(LabelFormatter.LABEL_VISIBLE);
It seems I was invited here by mistake, nevertheless I have something to say:
|
Thank you for your great advice! |
@manabu-nakamura @pubiqq so I think the performance concern is still relevant here - since material-components-android/lib/java/com/google/android/material/slider/BaseSlider.java Lines 353 to 358 in 8eae09d
meaning it would walk up the full view hierarchy on every scroll + global layout change. |
The performance loss is negligible (few |
I don't think there seem to be any performance issues, but I tried rewriting the program. |
@@ -354,6 +354,8 @@ abstract class BaseSlider< | |||
private final ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = | |||
this::updateLabels; | |||
|
|||
private boolean isVisible = isShown(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@manabu-nakamura did you test this? I don't think isShown()
will really work here since when the view class / object is initially constructed, it is not added to the hierarchy yet. I think the field should be left uninitialized and then you can do isVisible = isShown();
in onAttachedToWindow()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually I'm thinking we can do isVisible = isShown()
in the constructor after the super()
call (that way the super class has at least processed the initial setVisibility()), and then also isVisible = isShown()
in onAttachedToWindow()
to account for the parent hierarchy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was able to run Test8 without any problems in the following cases:
- BottomAppBar
- android:visibility="visible"
- android:visibility="invisible"
- android:visibility="gone"
https://docs.oracle.com/javase/specs/jls/se23/html/jls-12.html#jls-12.5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I modified the initialization of isVisible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BottomAppBar? The case I'm referring to is when the parent of the Slider is invisible/gone, isShown() won't work correctly in the constructor because the parent hierarchy is not assigned yet:
https://stackoverflow.com/questions/7099249/using-view-getparent-in-views-constructor
I'll add it to onAttachedToWindow()
when importing the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much. I see.
I was able to run Test8 without any problems in the following cases:
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:fitsSystemWindows="true"
android:visibility="visible"> <=
<com.google.android.material.slider.Slider
android:id="@+id/slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:labelBehavior="visible" />
</com.google.android.material.bottomappbar.BottomAppBar>
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:fitsSystemWindows="true"
android:visibility="invisible"> <=
<com.google.android.material.slider.Slider
android:id="@+id/slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:labelBehavior="visible" />
</com.google.android.material.bottomappbar.BottomAppBar>
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:fitsSystemWindows="true"
android:visibility="gone"> <=
<com.google.android.material.slider.Slider
android:id="@+id/slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:labelBehavior="visible" />
</com.google.android.material.bottomappbar.BottomAppBar>
closes #4319
I'm worried about performance: