macroid
macroid copied to clipboard
enhancement: access to layoutparams after lp tweak
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 possible
Alternatively, figure out a good way of creating AttributeSets so that one can do
lp[A](Map(...).toAttributeSet)
etc.
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 AttributeSets 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" [email protected] 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
lpgeneration?
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)
}