Skip to content
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

[Image View] Fix multiple contentPadding issues #2609

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

jpmcosta
Copy link

@jpmcosta jpmcosta commented Mar 21, 2022

Solution

Closes #2063.

Should fix the following contentPadding issues:

  • contentPadding getters returning outdated values when app:contentPaddingStart or app:contentPaddingEnd are defined in xml;
  • contentPadding being applied twice, if setContentPadding or setContentPaddingRelative are called before the view is measured;
    • in this case, the shape mask is also affected to have padding even if only contentPadding is defined.
Ensure that startContentPadding and endContentPadding values can be
updated programmatically, instead of being set in xml only. This
prevents getters from returning outdated values.
@google-cla
Copy link

google-cla bot commented Mar 21, 2022

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

For more information, open the CLA check for this pull request.

@@ -140,6 +134,24 @@ public ShapeableImageView(Context context, @Nullable AttributeSet attrs, int def

attributes.recycle();

if (hasContentPadding()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems not right to update paddings before layout direction is resolved? The content padding values thus got might be wrong.

Copy link
Author

@jpmcosta jpmcosta Apr 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that, once padding is set in View, resetResolvedPadding() ensures that resolvePadding() will be called when appropriate. I also couldn't find any documentation stating that setPadding() or setPaddingRelative() should only be called when layout direction is resolved.

So, I would say that the previous workflow was unnecessary. However, I might be missing something and I'm sorry if that's the case.

I couldn't reproduce any issues while testing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not about get/setPadding() but how we get content padding, which relies on View.getLayoutDirection() to decide which content padding should be used. If this call happens before the layout direction is resolved, there might be a problem.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View.resolvePadding() should adjust the padding accordingly, once the layout direction is resolved.

Again, I might be missing something. Do you have an example, even if theoretical, that I can test?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View.resolvePadding() also makes use of View.getLayoutDirection() to decide if it's RTL, which, again, may not be resolved yet in the constructor.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how I see it:

  • View.resolvePadding() is usually not called in the constructor;
  • In this case, it will be called, because we need to get the current padding values (e.g., calling super.getPaddingStart(), etc.);
  • However, setting padding also calls View.resetResolvedPaddingInternal(), ensuring that View.resolvePadding() will be called again later, when View.getLayoutDirection() is properly resolved;
  • In the meantime, even if View.getLayoutDirection() is not accurate, everything will be consistent.

So, I don't see any issues that don't already occur when setting/getting the regular padding.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, imagine this scenario -

If you set paddingStart and contentPaddingRight at the same time. Before RTL is resolved, in the overridden setPaddingRelative(), contentPaddingRight will be added to paddingEnd instead of paddingStart - which is wrong, because it should be added to paddingStart instead.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's definitely an issue. Somehow I wasn't considering cases where one would mix absolute regular padding with relative content padding, or the other way around. 👍

@jpmcosta jpmcosta marked this pull request as draft April 18, 2022 19:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants