clojure-android / neko

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

find-view not finding views #58

Closed kenrestivo closed 8 years ago

kenrestivo commented 8 years ago
  (debug/safe-for-ui
   (view/find-view (debug/*a) ::playing-button))

returns nil

but the view that is set at onCreate time definitely has an element with that id, and I can see it displayed. When run from inside the program (rather than the repl), using this instead of (debug/*a), it also returns nil.

Interestingly, in attempting to debug this, I tried this from a REPL:

  (debug/safe-for-ui
   (activity/get-decor-view (debug/*a)))

And got a strange

#object[com.android.internal.policy.impl.PhoneWindow$DecorView 0xa104b800 "com.android.internal.policy.impl.PhoneWindow$DecorView@a104b800"]

returned instead of my view.

I'm not sure what's going on here.

alexander-yakushev commented 8 years ago

That's a correct DecorView object you are getting. Can you call (.getTag) on it?

kenrestivo commented 8 years ago
  (debug/safe-for-ui
   (-> (debug/*a)
       activity/get-decor-view
       .getTag))

=> nil

alexander-yakushev commented 8 years ago

Yes, something's fishy going on. Can you please show the code of your onCreate? Also, are you sure (debug/*a) returns the very activity you think it should return?

kenrestivo commented 8 years ago

Gladly: https://github.com/kenrestivo/spazradioapp/blob/new-neko/src/clojure/org/spaz/radio/player.clj#L201

Thanks for your help!

alexander-yakushev commented 8 years ago

Sorry, I totally forgot. To enable this behavior (finding views by :id directly in their activity) you shouldn't call this anymore:

(set-content-view! activity (make-ui activity ui-tree))

But instead:

(set-content-view! activity ui-tree)

In other words, you don't have to call make-ui explicitly anymore, set-content-view! does it automatically now.

alexander-yakushev commented 8 years ago

Also, if you use Emacs, you can add this to your init.el:

  (add-hook 'clojure-mode-hook
            #'(lambda ()
                (put 'defactivity 'clojure-backtracking-indent '(4 (2)))))

This will make indentation in defactivity nice again.

kenrestivo commented 8 years ago

Pilot error! I don't need to make-ui before handing this to set-content-view!

Thanks!

alexander-yakushev commented 8 years ago

You are welcome! Glad it works now.

kenrestivo commented 8 years ago

Um, I spoke too soon. .getTag works, but find-view does not still

  (debug/safe-for-ui
   (view/find-view (debug/*a) ::playing-text))

=> nil

kenrestivo commented 8 years ago

Also returns nil:

(debug/safe-for-ui
   (-> (debug/*a)
       activity/get-decor-view
       .getTag
       (get ::playing-text)))

=> nil

the get-decor view is in fact returning the correct layout, I can see the :id . But it's not in the tags.

alexander-yakushev commented 8 years ago

Heh, I see the problem now. It is all those :id-holders you have in your layout which are redundant. Whenever you set :id-holder attribute for a container, it means that all its internal elements will be caught by him and stored in its tag. It is useful when you have a listview and each element is compound - so you keep references to all individual pieces inside each element container.

Now to set-content-view!. It implicitly puts :id-holder on top-level DecorView, so all those :id's propagate all the way up to it — unless someone caughts them in the middle, as in your case.

TL;DR: Remove :id-holders from your layout and you'll be fine :).

kenrestivo commented 8 years ago

That's it! Thanks for making the whole API simpler. I