Clojure 上的 React-native - 通过 id 和 scrollTo 获取 ScrollView 内的视图

React-native on Clojure - Get the ScrollView by id and scrollTo a view inside the ScrollView

我有一张带有标记列表的地图。我在地图下方的 ScrollView 中还有一个视图列表(包含标记项目的详细信息)。

当我点击地图内的标记时,我需要向下滚动到 ScrollView 内的特定视图。

这是我的代码。

(defn render-link [ctx art]
  (let [{:keys [dimensions]} (get-dimensions)
        route (current-route> ctx)
        name (:name art)
        photos ((:photos art))
        campus ((:campus art))
        thumbnail ((:thumbnail art))
        art-selector (if thumbnail thumbnail (first photos))
        photo-url (str "https:" (image-url (when (seq photos) (get-in art-selector [:file :url])) :1x1))]
    [touchable-highlight {:key (:id art)
                          :on-press #(navigate-replace! (assoc route :active-id (:id art)))}
     [view {:style {:width (:width dimensions)
                    :background-color (:lightest-gray colors)
                    :height 60
                    :flex-direction "row"
                    :justify-content "center"
                    :flex-wrap "nowrap"
                    :border-bottom-width 1
                    :border-bottom-color (:semi-gray colors)}}
      [image {:source {:uri photo-url}
              :resize-mode "cover"
              :style {:width 60}}]
      (if (= (:id art) (:active-id route))
        [view {:style {:width 4
                       :border-left-width 4
                       :border-left-color (:red colors)}}]
        [view {:style {:width 4
                       :border-left-width 4
                       :border-left-color (:lightest-gray colors)}}])
      [view {:style {:flex 1
                     :align-items "center"
                     :flex-direction "row"
                     :padding-horizontal 12}}
       [view {:style {:flex 1
                      :flex-direction "column"
                      :justify-content "center"}}
        [text {:number-of-lines 1
               :style {:color (:gray colors)
                       :font-size 18 
                       :font-weight "500"}} (str/trim name)]
        [text {:number-of-lines 1
               :style {:color (:gray colors)}} (:name campus)]]
       [view {:style {:flex-direction "row"}}
        [touchable-highlight {:underlay-color "transparent"
                              :on-press #(navigate-go! {:key "add-to-list" :id (:id art)})}
         [image {:source img-add-existing
                 :resize-mode "contain"
                 :style {:margin-horizontal 12
                         :width 30
                         :height 30}}]]
        [touchable-highlight {:underlay-color "transparent"
                              :on-press #(navigate-go! {:key "routing" :id (:id art)})}
         [image {:source img-location
                 :resize-mode "contain"
                 :style {:margin-horizontal 12
                         :width 30
                         :height 30}}]]]]]]))

(defn render [ctx]
  (let [{:keys [top-padding
                dimensions]} (get-dimensions)
        nearby (sub> ctx :nearby-art-pieces)
        route (current-route> ctx)
        list-is-expanded? (r/atom false)]
    (fn []
      [view {:style {:flex 1
                     :width (:width dimensions)
                     :margin-top top-padding}}
       [(ui/component ctx :top-bar)] 
      (when (sub> ctx :show-map?)
         [view {:style {:flex 1}}
          [(ui/component ctx :map) {:style {:width (:width dimensions)
                                            :flex 1}}
           (when-let [user-location (select-keys (:coords (sub> ctx :geolocation)) [:latitude :longitude])]
             [user-marker {:coordinate user-location}])
           (doall
            (map (fn [art]
                   (when-let [location (set/rename-keys (:geoLocation art) {:lat :latitude :lon :longitude})] 
                     (if (= (:id art) (:active-id (current-route> ctx)))
                       [active-marker {:key (:id art)
                                       :coordinate location}]
                       [marker {:key (:id art)
                                :coordinate location
                                :on-press #(navigate-replace! (assoc route 
                                :active-id (:id art))}]))) nearby))]])
       [view {:style {:height (if (= false @list-is-expanded?) 80 (+ 20 (* 60 (min (max 1 (count nearby)) 4))))
                      :width (:width dimensions)
                      :margin-bottom 60}}
        [touchable-highlight {:on-press #(swap! list-is-expanded? not)}
         [view {:style {:height 20
                        :width (:width dimensions)
                        :background-color (:gray colors)}}]]
        [scroll-view {:id "art-list-view"}
         (doall (map (fn [art]
                       (render-link ctx art)) nearby))]]
       [(ui/component ctx :tab-bar)]
       [(ui/component ctx :sidebar)]])))

在按下标记时,我需要向下滚动 ID 为 "art-list-view" 的 ScrollView。

有人可以帮忙吗?

我可以通过使用动画滚动视图和下面的代码来解决这个问题:

[marker {:key (:id art)
                                :coordinate location
                                :on-press (fn []
                                  (when-let [s @scroll-atom]
                                   (navigate-replace! (assoc route :active-id (:id art)))
                                   (ocall s "_component.scrollTo" #js {:x 0 :y (* index 60) :animated false})))}]

列表视图:

[animated-scroll-view {:id "art-list-view"
                                :ref #(reset! scroll-atom %)}
         (doall (map (fn [art]
                       (render-link ctx art)) nearby))]]