clojure-android / lein-droid

A Leiningen plugin for building Clojure/Android projects
Eclipse Public License 1.0
645 stars 56 forks source link

.getText on an EditText returns empty String #55

Closed krisc closed 11 years ago

krisc commented 11 years ago

I am having trouble getting the value of an EditText field in my app. I have something like this to bind ids.

(defn main-layout [] (make-ui
                   [:linear-layout {:orientation :vertical,
                                    :id-holder :true}
                     [:linear-layout {}
                       [:edit-text {:hint "name here",
                                    :id ::name}]
                       [:button {:text "+ Event",
                                 :on-click (fn [_] ( ... ))}]]
                     [:text-view {:text @listing,
                                  :id ::listing}]]))

Now when I call:

(::name (.getTag (main-layout)))

It returns an EditText as expected. However, after entering some text into the EditText field in my app then calling:

(str (.getText (::name (.getTag (main-layout)))))

it just returns "".

alexander-yakushev commented 11 years ago

You must understand that calling main-layout function every time creates a new set of UI objects. And since by default EditText is empty, that is what you receive.

What you want to do is to add the following line to top linear-layout's attributes:

:def `mylayout ;; Note the backtick, it is important

What this will do is define mylayout variable in your current namespace and bind UI widget to it. Then you can use it to reference your UI tree and get subelements from it using .getTag.

And of course nothing stops you from setting :def to subelements as well, so you can reference them directly.

And one last thing, in order to compile code like this later using AOT (not just in repl) you'll have to put a (declare ^android.widget.LinearLayout mylayout ...) somewhere at the top.

krisc commented 11 years ago

Thank you, that makes a lot of sense. So you don't recommend the use of the :id then?

alexander-yakushev commented 11 years ago

:id serves a different purpose. Suppose you have a ListView, where every item is some complex view (layout with widgets inside). You obviously can't bind every subitem to a var, and the only thing you are provided with by callbacks and update function is the top level view. Then you need to define it as :id-holder and put :ids to subelements so you can find them later. This is an implementation of Android's ViewHolder pattern.