使用React Native

时间:2019-06-16 10:57:49

标签: android ios react-native

我需要一些帮助来弄清楚如何在React Native中精确绘制。我以前在(本机)iOS上已经做过这种事情,但在Android上还没有,所以可能我可能会缺少Android的东西,但我最好只使用React Native方法解决此问题,而不必借助实现自定义视图。

例如,我试图画一张具有乐谱的谱号:

Example of a staff

我正在水平模式下使用React Native FlatList进行此操作。我在内容单元格内绘制垂直线作为分隔符,绘制水平线。这就是我所关心的,还没有数字等。

我尝试了两种使用React Native进行绘制的方法:

  1. PNG;我提供了普通的@ 2x和@ 3x版本,并在ImageBackground标签中进行渲染。这在iOS上有效,但在Android上,线条无法完美对齐,因此您可能会发现垂直线和水平线无法很好地连接,存在间隙,并且垂直方向的组件尺寸不相同,因此它们太短。这是因为@ 2x和@ 3x在iOS上是像素完美的,但仍需要在Android上缩放吗?
  2. SVG(react-native-svg);这给出了类似的问题。同样,在iOS上效果还不错,但在Android上像素排列不正确。为了说明这一点,请参见以下三个屏幕截图。

iOS上的SVG:接近完美(但不是100%): iOS

Android低分辨率设备(emu)上的SVG:很奇怪,不同部分的高度有何不同:

Android low res

Android高分辨率设备(emu)上的SVG:水平线不连续,垂直线超出上下人员范围:

Android high res

我不明白为什么这会导致它在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)]))}]])

0 个答案:

没有答案