clojure-android / neko

The Clojure/Android Toolkit
Other
297 stars 36 forks source link

make-ui and ahead-of-time compilation #23

Open BartAdv opened 10 years ago

BartAdv commented 10 years ago
;;;;;;; this gives IllegalArgumentException while compiling
(def ui (make-ui [:linear-layout {}
                  [:text-view {:text "doh"}]]))

(defactivity foo.bar.MainActivity
  :def a
  :on-create
  (fn [this bundle]
    (on-ui
     (set-content-view! a
      (make-ui [:linear-layout {}
                [:text-view {:text "Hello from Clojure!"}]])))))
;;;;;; ^^ this does not - what's the deal??

This does not occur when I disable aot for the given namespace.

PS. I'm not really sure whether it's really a neko issue, or whether maybe it belongs to lein-droid or whether is it beyond the scope of clojure-android, I was just unable to figure out the cause and I decided to report it here.

alexander-yakushev commented 10 years ago

Using def you force the underlying code to be executed when it is loaded (thus, during AOT-compilation too). Use defn instead of def to defer the execution, or def only general Clojure things (like, only UI structure, without calling make-ui on it).

Similar issue: https://github.com/clojure-android/lein-droid/issues/57

BartAdv commented 10 years ago

Right, but that kinda invalidates usefulness of id-holders as described in doc sample: https://github.com/clojure-android/neko/blob/master/src/clojure/neko/ui/traits.clj#L407, but as we already started discussion on mailing list, having references to those built objects would not be desirable. I need to find my way into id-related gui stuff :)

alexander-yakushev commented 10 years ago

Wow, that is one terrible example. Sorry for that. There is a wrong example on the wiki as well, I've just fixed it. https://github.com/clojure-android/neko/wiki/User-interface#wiki-list-of-most-useful-traits

BartAdv commented 10 years ago

OK, but I'm still at total loss now on how to easily refer some other element from event handler - a seemingly basic operation:

[:linear-layout {:id-holder true}
  [:button {:text "do something"
                 :on-click (fn [w] (comment "What to do here to manipulate ::regid-txt?"))}]
  [:edit-text {:id ::regid-txt}]]
alexander-yakushev commented 10 years ago

OK, sorry for the such a late answer. There's currently no sane way to get an element by ID from an activity, but I plan to solve it in the nearest future. This would probably involve setting id-holder for the root Activity view.

alexander-yakushev commented 10 years ago

OK, I've started moving towards the solution. neko 3.1.0-SNAPSHOT from Clojars contains a modified version of find-view which allows to extract views by their :id from container Views or Activities. set-content-view! was also redesigned to support this. Please see an example that follows:

(ns org.bytopia.test.main
  (:use [neko.activity :only [defactivity *a set-content-view!]]
        [neko.find-view :only [find-view find-views]]
        [neko.threading :only [on-ui]]))

(defactivity org.bytopia.test.MainActivity
  :on-create
  (fn [this bundle]
    (on-ui
     (set-content-view! (*a)
      [:linear-layout {}
       [:button {:text "do something"
                 :on-click (fn [w]
                             (let [regid (find-view (*a) ::regid-txt)]
                               ...
                               ))}]
       [:edit-text {:id ::regid-txt}]]))))

Notice the following changes:

Please give it a try and say if I've chosen a correct direction.