Open pfn opened 10 years ago
setting layout margins is definitely a pain point
currently I have to run:
lp + margins
where margins is something ugly like
tweak { v: View => v.getLayoutParams.asIntanceOf[ViewGroup.MarginLayoutParams] ...}
and it requires having set lp beforehand
Yeah, I actually avoid using margins, replacing them with padding where possible :) From your suggestions, I think AttributeSet
s are the way to go, as it will also solve #30. Unfortunately, I don’t have any time to work on this now. Would you or @dant3 be interested in looking into AttributeSet
stuff?
After some experiments with macroid, I too feel lp as a pain point (if not using xml layouts :stuck_out_tongue:). AttributeSet
api is definitely way to go to solve this, and similar issues. Not sure if I have enough time currently, but I could look at it later, if nobody will pick it up before.
@dant3 I think we can agree that Android’s LayoutParams
API itself is a bit of a mess ;)
By the way, how much is it desired to change layout params after layout? If they are only set once, maybe widgets could be wrapped into something like this before being added to the layout:
// isParams is generated by an implicit macro
case class LP[L <: ViewGroup, +W <: View, X](view: W, params: X)(implicit isParams: IsParams[X, L])
I guess this could offer more type safety if done right, but not sure about the details yet. What do you think?
I don't understand how this would streamline the lp generation?
isParams only links VG and VG.LP?
Sent from my phone On Aug 17, 2014 3:38 AM, "Nick" notifications@github.com wrote:
By the way, how much is it desired to change layout params after layout? If they are only set once, maybe widgets could be wrapped into something like this before being added to the layout:
// isParams is generated by an implicit macrocase class LP[L <: ViewGroup, +W <: View, X](view: W, params: X)(implicit isParams: IsParams[X, L])
I guess this could offer more type safety if done right, but not sure about the details yet. What do you think?
— Reply to this email directly or view it on GitHub https://github.com/macroid/macroid/issues/34#issuecomment-52418618.
Oh, I suppose the case class can take a function to operate on the params.
Rather than params: X it should be params: (X => Unit)?
Also, interestingly, it'd be nice if WindowManager.LayoutParams could be supported as well. It isn't a view group... But one applies the layout params to content views..
Sorry for not being elaborate enough. To give an example, if we wanted to add a Button
to a LinearLayout
, we would wrap it into
LP[LinearLayout, Button, LinearLayout.LayoutParams](w[Button], new LinearLayout.LayoutParams(...))
although your idea with X ⇒ Unit
works as well. The way isParams
works is that there will be automatic implicits for these relations:
implicitly[IsParams[LinearLayout.LayoutParams, LinearLayout]]
implicitly[IsParams[ViewGroup.LayoutParams, LinearLayout]]
...
Does this make sense?
To deal with WindowManager.LayoutParams
, we could provide an alternative version of setContentView
(also see #22) that takes something like Ui[LP[View]]
(LP
will need to drop the L <: ViewGroup
restriction).
I don’t understand how this would streamline the
lp
generation?
Oh well, this is somewhat orthogonal, but I thought extra type safety might help to deal with this horrible API. As far as configuring the actual params is concerned, AttributeSet
still seems the way to go.
This is basically what I came up with for my own thing.
abstract class LpRelation[V <: ViewGroup, LP <: ViewGroup.LayoutParams : ClassTag] {
def lpType = implicitly[ClassTag[LP]].runtimeClass
def lp(args: Any*) = lpType.getConstructor(
args map { a =>
val c = a.getClass
primitiveMap.getOrElse(c, c)
}:_*).newInstance(args map (_.asInstanceOf[AnyRef]): _*).asInstanceOf[LP]
}
implicit object LLRelation extends LpRelation[LinearLayout, LinearLayout.LayoutParams]
implicit object TRRelation extends LpRelation[TableRow, TableRow.LayoutParams]
Oh, can't forget the rest.
def lp2[V <: ViewGroup,LP <: ViewGroup.LayoutParams, C](args: Any*)
(p: LP => C)
(implicit r: LpRelation[V,LP]) = tweak {
v: View =>
val lp = r.lp(args: _*)
p(lp)
v.setLayoutParams(lp)
}
many layout params require field changes instead of only constructor parameters (e.g. gravity, span, relative layout stuff, etc. [yes, there's RuleRelativeLayout, but that's besides the point]).
I don't have a good solution for this yet, but maybe something like an optional parameter set, e.g.
lp[A](...)(Map(field -> value))
or
lp[A](...) { p: A.LayoutParams(????) => p.... }
// I don't see how this is possibleAlternatively, figure out a good way of creating AttributeSets so that one can do
lp[A](Map(...).toAttributeSet)
etc.