Мне нужна помощь, чтобы понять, как именно рисовать в React Native.Я делал подобные вещи раньше на (родной) iOS, но еще не на Android, поэтому потенциально я могу упустить Android-вещь, но я бы предпочел решить эту проблему, используя только методы React Native, не прибегая к реализации пользовательских представлений.
Я пытаюсь нарисовать посох музыкальной партитуры, например:
![Example of a staff](https://i.stack.imgur.com/y6al2.png)
Я делаю это с помощью React NativeFlatList
в горизонтальном режиме.Я рисую вертикальные линии как разделители и горизонтальные линии внутри ячеек контента.На данный момент это все, что меня интересует, но не цифры и т. Д.
Я попробовал два способа рисования этого с помощью React Native:
- PNG;Я поставляю обычные версии @ 2x и @ 3x и отображаю их в тегах
ImageBackground
.Это работает на iOS, но на Android линии не выстраиваются идеально, так что некоторые считают, что вертикальные и горизонтальные линии плохо соединяются, есть разрывы, и вертикально компоненты не имеют одинаковый размер, так что онислишком коротко.Это из-за того, что @ 2x и @ 3x идеально подходят для iOS, но все же должны быть масштабированы для Android? - SVG (
react-native-svg
);это дает похожие проблемы.Опять же, на iOS результаты довольно хорошие, но на Android пиксели не выстраиваются должным образом.Чтобы проиллюстрировать это, см. Следующие три снимка экрана.
SVG на iOS: близко к совершенству (но не на 100%): ![iOS](https://i.stack.imgur.com/Xp1fc.png)
SVG включенAndroid-устройство с низким разрешением (эму): очень странно, как высоты разных частей сильно различаются:
![Android low res](https://i.stack.imgur.com/vLydS.png)
SVG на устройстве высокого разрешения Android (эму): горизонтальная линия не является непрерывной, и вертикальные линии выходят за пределы персонала сверху и снизу:
![Android high res](https://i.stack.imgur.com/FKaJ1.png)
Я не понимаю, почему это получаетсякак это происходит на Android.Я не уверен, что использую правильный путь для достижения этой цели. Какой метод я должен использовать для этого? Любая помощь очень ценится!
Ниже приведен соответствующий исходный код.Он написан на ClojureScript, но даже если вы с ним не знакомы, вы сможете распознать способ построения SVG.Я осторожно использовал полупиксельные значения для координат линии и окончаний квадрата, чтобы теоретически все выровнялось точно по пикселям.
(defn bar-lines [width]
(take 5 (map (fn [y] ^{:key (str y)}
[:> Line {:x1 0.5 :y1 y :x2 (+ 0.5 (dec width)) :y2 y
:stroke-width 1 :stroke "black"
:stroke-linecap "square"}])
(iterate (partial + 8) 0.5))))
(defn cell [details]
(let [item (details "item")
num (item "measureNumber")]
[:> ViewOverflow {:style {:width 68 :height 65}}
[:> Svg {:height 34 :width 68 :view-box "0 0 68 33"
:style {:position "absolute" :bottom 0}}
(bar-lines 68)]]))
(defn single-line-separator []
[:> ViewOverflow {:style {:width 1 :height 65}}
[:> Svg {:height 34 :width 1 :view-box "0 0 1 33"
:style {:position "absolute" :bottom 0}}
[:> Line {:x1 0.5 :y1 0.5 :x2 0.5 :y2 32.5 :stroke-linecap "square" :stroke-width 1 :stroke "black"}]]])
(defn double-line-separator []
[:> ViewOverflow {:style {:width 3 :height 65}}
[:> Svg {:height 34 :width 3 :view-box "0 0 3 33"
:style {:position "absolute" :bottom 0}}
[:> Line {:x1 0.5 :y1 0.5 :x2 0.5 :y2 32.5 :stroke-linecap "square" :stroke-width 1 :stroke "black"}]
[:> Line {:x1 2.5 :y1 0.5 :x2 2.5 :y2 32.5 :stroke-linecap "square" :stroke-width 1 :stroke "black"}]
(bar-lines 3)]])
(defn separator [props]
(if (show-double-bar? (.-measureNumber (.-leadingItem props)))
(double-line-separator)
(single-line-separator)))
(defn header []
[:> rn/View {:style {:width 15 :height 65}}
[:> Svg {:height 34 :width 15 :view-box "0 0 15 33"
:style {:position "absolute" :bottom 0}}
(bar-lines 15)
[:> Line {:x1 14.5 :y1 0.5 :x2 14.5 :y2 32.5 :stroke-linecap "square" :stroke-width 1 :stroke "black"}]]])
(defn footer []
[:> rn/View {:style {:width 11 :height 65}}
[:> Svg {:height 34 :width 11 :view-box "0 0 11 33"
:style {:position "absolute" :bottom 0}}
[:> Line {:x1 0.5 :y1 0.5 :x2 0.5 :y2 32.5 :stroke-linecap "square" :stroke-width 1 :stroke "black"}]
[:> Line {:x1 4.5 :y1 1.5 :x2 4.5 :y2 31.5 :stroke-linecap "square" :stroke-width 3 :stroke "black"}]
(bar-lines 3)]])
(defn Staff [styles]
[:> rn/View styles
[:> rn/FlatList
{:data (clj->js (mapv (fn [n] {:key (str n) :measureNumber n}) (range 1 4)))
:horizontal true
:Cell-renderer-component ViewOverflow
:List-header-component #(r/as-element [header])
:List-footer-component #(r/as-element [footer])
:Item-separator-component #(r/as-element [separator %])
:render-item (fn [details] (r/as-element [cell (js->clj details)]))}]])