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

RCTUIManager.measure not working on Android #12966

Closed
anshul-kai opened this issue Mar 16, 2017 · 17 comments
Closed

RCTUIManager.measure not working on Android #12966

anshul-kai opened this issue Mar 16, 2017 · 17 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@anshul-kai
Copy link

Description

RCTUIManager.measure is not working on Android. Trying this.refs.myRef.measure() doesn't give any results either.

Reproduction

import { findNodeHandle } from 'react-native';
const RCTUIManager = require('NativeModules').UIManager;

RCTUIManager.measure(findNodeHandle(this.refs.myRef), (x, y, width, height, pageX, pageY) => {
      // Returns valid values on iOS but undefined on Android
});

Additional Information

  • React Native version: 0.42.0
  • Platform: Android
  • Operating System: MacOS
  • Dev tools: Android Studio 2.3
@anshul-kai anshul-kai changed the title Measure RCTUIManager.Measure not working on Android Mar 16, 2017
@anshul-kai anshul-kai changed the title RCTUIManager.Measure not working on Android RCTUIManager.measure not working on Android Mar 16, 2017
@hey99xx
Copy link

hey99xx commented Mar 16, 2017

Can you show me your view with the ref? I suspect you have the issue I've previously opened in #9382

@anshul-kai
Copy link
Author

Adding style={{opacity: 1}} did the trick. Thanks a lot!

Referring to your comment in #9382, what exactly do you mean by collapsable property?

Now I always force it to be created with collapsable property.

Although an annoyance, should I just follow your lead and close out this issue?

@hey99xx
Copy link

hey99xx commented Mar 16, 2017

So style={{opacity: 1}} is what I used until I understood the issue.

Collapsable property is explained in https://facebook.github.io/react-native/docs/view.html#collapsable

Views that are only used to layout their children or otherwise don't draw anything may be automatically removed from the native hierarchy as an optimization. Set this property to false to disable this optimization and ensure that this View exists in the native view hierarchy.

However, some of UIManager functions such as measure expect to find a native view; and when it can't it returns undefined values instead of throwing an error. Really it would be better to throw an error. React unfortunately is not intelligent to know you would be measuring the view in the first place.

Putting an explicit style is one way to disable the optimization; because now the view has to be created with special drawing properties. But the real fix is putting collapsable={false} on the view you will be measuring to disable the optimization by the documentation.

@anshul-kai
Copy link
Author

Makes sense. Thank you @hey99xx!

@itinance
Copy link
Contributor

Having the same issue with Views that are rendered within ListView. For the visible first rows, RCTUIManager.measure receives valid data on Android. But on the invisible rows every value is undefined.
On IOS everything works fine and es expected. Running RN 0.42.

I also tried out style={{opacity: 1}} and collapsable={false}. Is doesn't matter if i pass those properties and styles or not.

@hey99xx
Copy link

hey99xx commented Apr 13, 2017

@itinance If you post your render method I can help you out.

@itinance
Copy link
Contributor

Thx @hey99xx , any ideas?

    return (
      <View ref="container"
        collapsable={false}
        style={s.container}
        onLayout={this.onLayout}
        >
        <TouchableWithoutFeedback
          onPress={this.onPress}
          onLongPress={this.onLongPress}
          accessibilityTraits="text"
          collapsable={false}
        >
          <View style={s.row}>
            {isMe ? null : (
              <UserAvatar size={48} name={user.name} defaultName="?" src={user.avatar} style={s.avatar} />
            ) }
            <View style={[s.content, isMe ? s.contentMe : null]}>
              <View style={[s.meta, isMe ? s.metaMe : null]}>
                <SemiBoldText style={s.metaText}>{isMe ? 'Me' : user.name}</SemiBoldText>
                <LightText style={s.metaText}>{sent.format('ddd DD/MM/YYYY h:mm a')}</LightText>
              </View>

            </View>
          </View>
        </TouchableWithoutFeedback>
      </View>
    )

The "container" node in the Stylesheet contains also "opacity:1"

@hey99xx
Copy link

hey99xx commented Apr 13, 2017

But on the invisible rows every value is undefined.

Is it possible that your list view is getting clipped before you start scrolling down? Maybe on iOS you have rendered the entire list view in the first render, while on Android that's not the case.
Can you try removeClippedSubviews={false} on your list view or its rows? Not sure if collapsable prop is applicable to TouchableWithoutFeedback btw.

@itinance
Copy link
Contributor

Yes, removeClippedSubviews={false} fixed it. Thank you @hey99xx !

@hey99xx
Copy link

hey99xx commented Apr 14, 2017

@itinance You should realize that removeClippedSubviews is a performance optimization, which you are now disabling. Related documentation:

A performance optimization for improving scroll perf of large lists, used in conjunction with overflow: 'hidden' on the row containers. This is enabled by default.

Although I am glad you are unblocked, I suggest you find a different solution to measure your views after scroll. Maybe onChangeVisibleRows can work.

@itinance
Copy link
Contributor

Thank you very much for the hint, @hey99xx. I will look at it and try it out.

@itinance
Copy link
Contributor

itinance commented Apr 14, 2017

Hey @hey99xx , onChangeVisibleRows works really fine and fits all our needs. At least on iOS. On Android this event is never fired unfortunately. There was an open Pullrequest since 14 Januar (!) in the pipeline, that was closed 14 days ago without any merge "as ListView is deprecated" 👎 👎 👎

@hey99xx
Copy link

hey99xx commented Apr 14, 2017

@itinance That's a shame. I was not aware it wouldn't get further bug fixes. You can look at if the new alternative FlatList has a way to do the same thing, possible through onViewableItemsChanged. I never used FlatList so I wouldn't be able to help you there. Good luck!

@hey99xx
Copy link

hey99xx commented Apr 14, 2017

Also, unless you have infinite scrolling and/or very long lists with lots of images (basically heavy-weight rendering needs) I wouldn't worry too much about clipping views.

@itinance
Copy link
Contributor

Just FYI, @hey99xx : the onViewableItemsChanged-Event of VirtualizedList/FlatList works fine unless one use react-native-infinite-scrollview, which is base component of gifted-chat.

@wulucxy
Copy link

wulucxy commented May 26, 2017

@hey99xx hi, thanks for your answer.
I encouter the same problem on android, besides removeClippedSubviews = {false}, we can't stand the performance problem。
do you have other solutions?

@shobulive
Copy link

sorcery!!!
style={{opacity:1 }} works like charms!!! thanks.

@facebook facebook locked as resolved and limited conversation to collaborators May 24, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

8 participants
@shergin @itinance @wulucxy @anshul-kai @hey99xx @shobulive @react-native-bot and others