These are chat archives for scala-android/sbt-android

19th
Aug 2016
Perry
@pfn
Aug 19 2016 00:02
@taig if you want to give it a try, you can clone https://github.com/pfn/iota and +publish-local, it's 2.0.0-SNAPSHOT, but I will probably publish that as 2.0.0 unless some glaring issue appears
Perry
@pfn
Aug 19 2016 00:49
@Taig themes and styles will have to come in a future iteration when it's better thought out (or if users have ideas on how to make it work nicely)
Perry
@pfn
Aug 19 2016 01:16
adding support for default values on the case class parameters can potentially help with styling and theming
Perry
@pfn
Aug 19 2016 04:42
yeah, gonna add support for default args, and the ability to treat the view tree as an iterator, so you can perform collection operations over it
Niklas Klein
@Taig
Aug 19 2016 07:55
@pfn I'll play with it later today. Would be nice if one could omit the container parameter and
Niklas Klein
@Taig
Aug 19 2016 08:02
inherit it instead from the viewtree
jhegedus42
@jhegedus42
Aug 19 2016 10:38
what is it better : to make own apps and sell them or to work as a contractor to make apps for someone else?
s/what is it better/what is better
@jhegedus42 I think there is basically no money in selling apps
jhegedus42
@jhegedus42
Aug 19 2016 10:39
selling own apps you mean
it's probably below 1% who break even
yeah.
jhegedus42
@jhegedus42
Aug 19 2016 10:39
hmm
might pay to write apps for other people though
jhegedus42
@jhegedus42
Aug 19 2016 10:40
interesting
so the android business is not paying very well...
I think the whole app thing only survives on the hopes of naive people
so you have the choice of being naive and hoping you belong to the 0.1%, or contract and work for naive people (and get paid in advance, I hope)
Rafal Wachol
@charafau
Aug 19 2016 10:47
same goes for ios ;)
still, mobile market is huge in japan
jhegedus42
@jhegedus42
Aug 19 2016 10:52
japan?
Rafal Wachol
@charafau
Aug 19 2016 10:52
yes
especially for games
jhegedus42
@jhegedus42
Aug 19 2016 10:53
pretty interesting situation
it's like music industry
Rafal Wachol
@charafau
Aug 19 2016 10:54
but 70% of all smartphones are iphones here
jhegedus42
@jhegedus42
Aug 19 2016 11:17
hmm
o
is it easier to develó f
jammed keyboard
is it easier to develop for iphone?
Rafal Wachol
@charafau
Aug 19 2016 11:19
same as for android
jhegedus42
@jhegedus42
Aug 19 2016 11:19
ok
machine learning is getting popular
Rafal Wachol
@charafau
Aug 19 2016 11:20
for many years :P
I would like to do it, but it's quite hard to get into company without previous experience
jhegedus42
@jhegedus42
Aug 19 2016 11:21
but its not so easy to do that as contractor/single person
Rafal Wachol
@charafau
Aug 19 2016 11:21
I'm not single person :D
jhegedus42
@jhegedus42
Aug 19 2016 11:21
:)
right
Rafal Wachol
@charafau
Aug 19 2016 11:22
maybe I could do some ML in our current user base
like spam posts
jhegedus42
@jhegedus42
Aug 19 2016 11:22
yeah
deep learning especially
it might be good idea to get a job doing deep learning
10 years from now it might be a huge thing...
Rafal Wachol
@charafau
Aug 19 2016 11:24
it's not all about deep learning..
jhegedus42
@jhegedus42
Aug 19 2016 11:24
yeah... true
but that's the one that is going to bring AI
IMHO
Rafal Wachol
@charafau
Aug 19 2016 11:26
we will see
I could do PhD :)
Rafal Wachol
@charafau
Aug 19 2016 11:27
yeah
I just reminded how my boss wanted to filter NG photos with caffee
and wanted to get it done in 2 weeks :D
or 1 week ?
anyway, this couldn't be done
in the end network had like 60% accuracy
jhegedus42
@jhegedus42
Aug 19 2016 11:28
yeah...
kinda unrealistic expectations
this might be a way to show expertise https://www.kaggle.com/
Rafal Wachol
@charafau
Aug 19 2016 11:31
didnt know about it
might be interesitng
like CTF for ML
jhegedus42
@jhegedus42
Aug 19 2016 11:33
yeah...
can compare your algorithm
probably need good hardware too
Rafal Wachol
@charafau
Aug 19 2016 11:34
I think so too
time ot buy two 1080s :D
jhegedus42
@jhegedus42
Aug 19 2016 11:35
yeah
stg like that
might be a lucrative business to invest into though....
Rafal Wachol
@charafau
Aug 19 2016 11:37
in the end you will be able to play a lot of AAA games ;D
jhegedus42
@jhegedus42
Aug 19 2016 11:37
in the worst case...
Rafal Wachol
@charafau
Aug 19 2016 11:58
it's important to relax ;)
jhegedus42
@jhegedus42
Aug 19 2016 12:00
true...
Perry
@pfn
Aug 19 2016 13:23
@Taig, yeah, I can't think of a way for the container to be generated automatically
not without ugly reflection at runtime
Niklas Klein
@Taig
Aug 19 2016 13:47
Too bad, but I was just thinking out loud. About to have an actual look at the tool now :thumbsup:
all the user facing bits are there, the implementation details are in ViewTreeMacro now
Niklas Klein
@Taig
Aug 19 2016 14:03
Styles would pretty much become traits, which is awesome
trait MyTextStyle extends ViewTree[TextView] {
   container.setTextColor( ... )
}
Or am I missing something here?
Perry
@pfn
Aug 19 2016 14:06
hmm, I had envisioned ViewTree to be only view groups
that's an interesting use case
Niklas Klein
@Taig
Aug 19 2016 14:38
How should I deal with Context? I was expecting to find an implicit Context in there already. Will the macro still work if I add that to the case class constructor?
conceptually ?
A glorified ArrayList ?
Perry
@pfn
Aug 19 2016 14:40
@Taig, why do you need context? that's provided with inflate
@Taig, you should be able to do container.getContext
Niklas Klein
@Taig
Aug 19 2016 14:41
Oh yeah, of course
Stupid me
Perry
@pfn
Aug 19 2016 14:41
@Taig, although, it's a problem I'm considering, particularly for default args
jhegedus42, cursor is analogous to resultset in jdbc
same thing, actually
jhegedus42
@jhegedus42
Aug 19 2016 14:47
thanks Perry
Niklas Klein
@Taig
Aug 19 2016 14:51
I'm definitely in love with your view dsl. It removes the huge pain point of xml-layouts with accompanying classes and lots and lots of boilerplate, and at the same time it doesn't scare me away like all the other alternatives did before.
A typical dsl might be the most obvious solution for view building, but I feel like the case class approach is an unexpected perfect fit.
Perry
@pfn
Aug 19 2016 14:55
which is part of the reason why the xml layouts suck
I solved the typed tree issue with xml layouts using TypedViewHolders
Perry
@pfn
Aug 19 2016 15:07
@Taig well, because case classes can easily form a typed tree hierarchy, none of the other solutions have that property
and for scala, it requires some relatively heavy macro machinery
@jhegedus42 for that matter, cursor is a very basic database term that is used pretty universally
@Taig also, the various layout decorators are fully typed, the IDE will complete them, but they will fail at compiletime if you use the wrong decorator, e.g. relativelayout rules in a non-relativelayout--kind of a cool feature
jhegedus42
@jhegedus42
Aug 19 2016 15:21
Perry
@pfn
Aug 19 2016 15:22
android sort of assumes a broad range of knowledge to work with various features
it's kind of why it was built on java
if you're completely familiar with java, moving to android is rather easy
every single concept translates directly
minus stuff that's irrelevant on android, like server-side ee bullshit
jhegedus42
@jhegedus42
Aug 19 2016 15:25
hmmm
yeah
Perry
@pfn
Aug 19 2016 15:26
otherwise, every other concept you learn is applicable: database, gui, threading, data structures, etc.
jhegedus42
@jhegedus42
Aug 19 2016 15:30
hmm
recycled concepts
Niklas Klein
@Taig
Aug 19 2016 15:53

It would be kinda cool if one could skip the case class definition sometimes. When I need a wrapper for instance (e.g. to add some padding or such) I would actually prefer to hide that from the hierarchy to keep it at simple as possible.

case class MyView(
    container: LinearLayout,
    title: TextView,
    description: TextView
) extends ViewTree[LinearLayout] {
    title.setTextSize( ... )

    description.setColor( ... )

    wrap[FrameLayout]( description ) { wrapper =>
        wrapper.setPadding( ... )
    }
}

Now the wrap function could easily be implemented at "runtime", but maybe you have a better idea or more thoughts about it.

Niklas Klein
@Taig
Aug 19 2016 16:41
I guess it would be possible to add a ClassTag for A and instantiate it via reflection, but I assume you want to avoid that at any cost?
Perry
@pfn
Aug 19 2016 17:25
yeah, I want to avoid runtime reflection completely
the hard part of that is ordering
all views in the arg list except for 'container' get added to the container
and the adding occurs after the body of MyView completes
so adding in the body like that would completely throw off the ordering of view insertion
this would affect z-ordering in all layouts, and linear ordering in linearlayouts :(
@Taig
Perry
@pfn
Aug 19 2016 17:33
stupid gitter client never notifies me of new messages here... pos
(btw, container doesn't have to be the first argument in the list, it can appear at any position)
I suppose what could be done is checking if the view already has a parent prior to adding, removing the parent from the container and then subsequently re-adding, this could retain order
@Taig would wrap have multiple args, or only ever 1?
if wrapping could be done to multiple views, it can be much more confusing, since removing parents can't be done arbitrarily
Perry
@pfn
Aug 19 2016 17:38
but if you'd only ever do this to a single view, this is very possible
(and yeah, this isn't possible with runtime reflection since you'd be stuck with the broken view ordering)
Perry
@pfn
Aug 19 2016 17:46
{
  val viewgroup8: android.widget.LinearLayout = new android.widget.LinearLayout(this);
  val view7: android.widget.TextView = new android.widget.TextView(this);
  val viewtree4: iotatest.AnotherTest.NestedItem = {
    val viewgroup9: android.widget.FrameLayout = new android.widget.FrameLayout(this);
    val view8: android.widget.TextView = new android.widget.TextView(this);
    val vt8: iotatest.AnotherTest.NestedItem = AnotherTest.this.NestedItem(viewgroup9, view8);
    if (view8.getParent().$bang$eq(null).$amp$amp(view8.getParent().$bang$eq(viewgroup9)))
      viewgroup9.addView(view8.getParent().asInstanceOf[ViewGroup])
    else
      viewgroup9.addView(view8);
    vt8
  };
  val vt9: iotatest.AnotherTest.Nested = AnotherTest.this.Nested(viewgroup8, view7, viewtree4);
  if (view7.getParent().$bang$eq(null).$amp$amp(view7.getParent().$bang$eq(viewgroup8)))
    viewgroup8.addView(view7.getParent().asInstanceOf[ViewGroup])
  else
    viewgroup8.addView(view7);
  if (viewtree4.container.getParent().$bang$eq(null).$amp$amp(viewtree4.container.getParent().$bang$eq(viewgroup8)))
    viewgroup8.addView(viewtree4.container.getParent().asInstanceOf[ViewGroup])
  else
    viewgroup8.addView(viewtree4.container);
  vt9
}
this is kind of what happens to the expanded code
pfn @pfn ponders
Perry
@pfn
Aug 19 2016 17:47
This message was deleted
Perry
@pfn
Aug 19 2016 18:02
@Taig another implication is that layout param decorators don't work properly, that may be a tougher nut to crack
e.g. going with your sample
case class MyView(
    container: RelativeLayout,
    title: TextView,
    description: TextView
) extends ViewTree[RelativeLayout] {
    title.setTextSize( ... )
    title.above(description) // oh no, but description got moved into FrameLayout
    description.setColor( ... )

    description.alignParentBottom() // but it just went into FrameLayout
    wrap[FrameLayout]( description ) { wrapper =>
        wrapper.setPadding( ... )
        title.above(wrapper) // this would be correct, however
        // mainly the problem is reconciling that both of these are valid?
        wrapper.alignParentBottom() // ok, this still works
        description.gravity(Gravity.BOTTOM) // how would this work?
    }
}
the example is a little contrived, but much worse if the outer container would be a relativelayout or something
Perry
@pfn
Aug 19 2016 18:07
updated the problem example ^^ to be a little clearer @Taig
Perry
@pfn
Aug 19 2016 18:19
the wrapper.alignParentBottom line would crash at runtime, as well, because a naive search would reveal that it's inside of a FrameLayout block, and that it should be injected with FrameLayout.LayoutParams, it would need to be injected with RelativeLayout.LayoutParams beforehand somehow... -- yeah, this appears to be a tough problem
case class MyView(
    container: RelativeLayout,
    title: TextView,
    description: TextView
) extends ViewTree[RelativeLayout] {
    title.setTextSize( ... )
    title.above(description) // oh no, but description got moved into FrameLayout
    description.setColor( ... )

    description.alignParentBottom() // but it just went into FrameLayout
    val wrapper = new FrameLayout(...)
    description.setLayoutParams(new FrameLayout.LayoutParams(....))
    wrapper.addView(description)
    wrapper.setPadding(...)
    wrapper.alignParentBottom()
}
not quite so nice, but this would be doable
pfn @pfn ponders some more
Niklas Klein
@Taig
Aug 19 2016 18:40
@pfn But you'd still have to remove description from container before adding it to wrapper I guess?
But yeah, it introduces a lot of problems
Perry
@pfn
Aug 19 2016 18:40
all addView calls occur after the class has been constructed
Niklas Klein
@Taig
Aug 19 2016 18:41
Oh. So you could simply skip that if there already is a parent?
Perry
@pfn
Aug 19 2016 18:41
I've already added code to help support this use-case:
      def addView(vg: Tree, view: Tree): Tree = {
        val v = c.Expr[View](view)
        val g = c.Expr[ViewGroup](vg)
        val a = c.Expr[Unit](Apply(Select(vg, newTermName("addView")), List(view)))
        // support the possibility of adding an anonymous level in the view hierarchy
        reify {
          if (v.splice.getParent != null && v.splice.getParent != g.splice)
            g.splice.addView(v.splice.getParent.asInstanceOf[ViewGroup])
          else
            a.splice
        }.tree
      }
Niklas Klein
@Taig
Aug 19 2016 18:41
Interesting
Perry
@pfn
Aug 19 2016 18:42
but wrapper must not be added to container explicitly, that will be handled by inflate after the object finishes initializing
and doing this would maintain the correct order
Niklas Klein
@Taig
Aug 19 2016 18:45
Correct order meaning that wrapper is inserted where otherwise description would have been? (I was actually thinking of wrapping an arbitrary amount of views ;))
Perry
@pfn
Aug 19 2016 18:45
yes
wrapping an arbitrary number of views presents a similar problem, but I guess that above logic might be amenable to supporting multiple views
need to check if v.splice.getParent.getParent != null
then just skip altogether
            if (v.splice.getParent.getParent == null)
              g.splice.addView(v.splice.getParent.asInstanceOf[ViewGroup])
so taht supports an arbitrary number of views, and the wrapper will take the place of the first child wrapped
Niklas Klein
@Taig
Aug 19 2016 18:57
Would it be possible to produce an anonymous ViewTree[FrameLayout] when wrap[FrameLayout]( a, b, c ) is called, treat the method body like the case class body and validate the enclosing scope that no configuration of a, b or c happens outside of the wrap scope?
Perry
@pfn
Aug 19 2016 19:00
that's something to ponder, I'm not sure
it feels like not really
at least not that approach
jhegedus42
@jhegedus42
Aug 19 2016 19:27
how many downloads can be considered a success if i wanna make a living by selling my app?
1 mill ?
100k?
10 mill?
considering the freemium model
Perry
@pfn
Aug 19 2016 19:31
you don't make a living selling your app
jhegedus42
@jhegedus42
Aug 19 2016 19:32
what about angry birds?
it's not impossible... but maybe playing
the lottery is less risky...
Perry
@pfn
Aug 19 2016 19:33
you generally don't make angry birds as an indie developer
jhegedus42
@jhegedus42
Aug 19 2016 19:34
but this is pretty interesting to hear
so larger teams are needed
the app needs to be part of something larger...
what would be the download count that would bring some significant amount of money? 1 mill ?
jhegedus42
@jhegedus42
Aug 19 2016 19:39
how much money can one make on 1 user? on average ?
Perry
@pfn
Aug 19 2016 19:40
that completely depends on how you monetize
and $0 on average
$0 on average?
Perry
@pfn
Aug 19 2016 19:42
close to that
jhegedus42
@jhegedus42
Aug 19 2016 19:45
hmm... surprising to hear that
Perry
@pfn
Aug 19 2016 19:48
surprising? the vast majority of apps don't make money
the vast majority of apps are free
Perry
@pfn
Aug 19 2016 20:18
@Taig hrm, looking impossible to expand the various layout decorator macros within a body like that...
there's now an "inflater factory" that is a PF String => View; this is a little unsafe part of the dsl, but it allows custom view creation for views that need to be handled specially
this is one area that can throw runtime exceptions, and be a little head-scratching and throw runtime exceptions (class cast errors)