React Native: получение позиции элемента
Я создаю компонент Image
с flexbox, чтобы быть в центре экрана, который работает очень хорошо. Теперь я хочу, чтобы второй компонент Image
отображался непосредственно в верхней части первой. На втором изображении используется абсолютное позиционирование. В настоящее время я просто угадываю пиксели так, чтобы он соответствовал, но, конечно, это неточно и слишком много усилий по поддержке.
Я в значительной степени искал коренной эквивалент React для jQuery .offset()
. Есть ли такая вещь, и нет ли лучшего способа достичь этого?
Ответы
Ответ 1
React Native предоставляет метод .measure(...)
, который выполняет обратный вызов и называет его смещениями и шириной/высотой компонента:
myComponent.measure( (fx, fy, width, height, px, py) => {
console.log('Component width is: ' + width)
console.log('Component height is: ' + height)
console.log('X offset to frame: ' + fx)
console.log('Y offset to frame: ' + fy)
console.log('X offset to page: ' + px)
console.log('Y offset to page: ' + py)
})
Пример...
Далее вычисляется компоновка настраиваемого компонента после его рендеринга:
class MyComponent extends React.Component {
render() {
return <View ref={view => { this.myComponent = view; }} />
}
componentDidMount() {
// Print component dimensions to console
this.myComponent.measure( (fx, fy, width, height, px, py) => {
console.log('Component width is: ' + width)
console.log('Component height is: ' + height)
console.log('X offset to frame: ' + fx)
console.log('Y offset to frame: ' + fy)
console.log('X offset to page: ' + px)
console.log('Y offset to page: ' + py)
})
}
}
Заметки об ошибках
-
Обратите внимание, что иногда компонент не заканчивает рендеринг до вызова componentDidMount()
. Если вы получаете нули в результате measure(...)
, то обертывание его в setTimeout
должно решить проблему, то есть:
setTimeout( myComponent.measure(...), 0 )
Ответ 2
Мне нужно было найти позицию элемента внутри ListView и использовать этот фрагмент, который работает как .offset
:
const UIManager = require('NativeModules').UIManager;
const handle = React.findNodeHandle(this.refs.myElement);
UIManager.measureLayoutRelativeToParent(
handle,
(e) => {console.error(e)},
(x, y, w, h) => {
console.log('offset', x, y, w, h);
});
Это предполагает, что у меня был ref='myElement'
на моем компоненте.
Ответ 3
Это, похоже, изменилось в последней версии React Native при использовании refs для вычисления.
Объявлять ссылки таким образом.
<View
ref={(image) => {
this._image = image
}}>
И найдите значение таким образом.
_measure = () => {
this._image._component.measure((width, height, px, py, fx, fy) => {
const location = {
fx: fx,
fy: fy,
px: px,
py: py,
width: width,
height: height
}
console.log(location)
})
}
Ответ 4
Вы можете использовать onLayout
, чтобы как можно скорее получить ширину, высоту и относительное положение кадра в компоненте, чтобы они доступно:
<View
onLayout={event => {
const layout = event.nativeEvent.layout;
console.log('height:', layout.height);
console.log('width:', layout.width);
console.log('x:', layout.x);
console.log('y:', layout.y);
}}
>
По сравнению с используя .measure()
, как показано в принятом ответе, это имеет то преимущество, что вам никогда не придется откладывать отсрочку вызовов .measure()
с помощью setTimeout
, чтобы убедиться, что измерения доступны, но недостаток, заключающийся в том, что он не дает вам относительных смещений по страницам, только относительные к кадру.
Ответ 5
Чтобы получить информацию о любом элементе, вы можете просто показать инспектора.
Откройте режим отладки (на симуляторе iOS в разделе "Аппаратное обеспечение" ) "Встряхните жест":
Реальный режим отладки
Это похоже на веб-DOM-инспектор, вы можете выбирать слои и видеть свойства стиля, а также позиции.
Реагировать с инсайдером