Skip to content
This repository has been archived by the owner on Jul 13, 2020. It is now read-only.

Theme support in Anko #143

Closed
fboldog opened this issue Feb 11, 2016 · 4 comments
Closed

Theme support in Anko #143

fboldog opened this issue Feb 11, 2016 · 4 comments

Comments

@fboldog
Copy link
Contributor

fboldog commented Feb 11, 2016

My proposal for theming comes from my example AnkoExtensions.kt and depends on appcompat-v7 ContextThemeWrapper (hidden from public api)

  • extending (ViewManager|Context|Activty).ankoView method:
fun wrapContextIfNeeded(ctx: Context,@StyleRes theme: Int): Context {
    return if (theme != 0 && (ctx !is ContextThemeWrapper || ctx.themeResId != theme)) {
        // If the context isn't a ContextThemeWrapper, or it is but does not have
        // the same theme as we need, wrap it in a new wrapper
        ContextThemeWrapper(ctx, theme)
    } else {
        ctx
    }
}

inline fun <T : View> ViewManager.ankoView(@StyleRes theme: Int = 0, factory: (ctx: Context) -> T, init: T.() -> Unit): T {
    val ctx = wrapContextIfNeeded(AnkoInternals.getContext(this), theme)
    val view = factory(ctx)
    view.init()
    AnkoInternals.addView(this, view)
    return view
}

inline fun <T : View> Context.ankoView(@StyleRes theme: Int, factory: (ctx: Context) -> T, init: T.() -> Unit): T {
    val ctx = wrapContextIfNeeded(this, theme)
    val view = factory(ctx)
    view.init()
    AnkoInternals.addView(this, view)
    return view
}

inline fun <reified T : View> ViewManager.customView(@StyleRes theme: Int = 0, init: T.() -> Unit): T {
    return ankoView(theme, { ctx -> AnkoInternals.initiateView(ctx, T::class.java) }) { init() }
}

inline fun <reified T : View> Context.customView(@StyleRes theme: Int = 0, init: T.() -> Unit): T {
    return ankoView(theme, { ctx -> AnkoInternals.initiateView(ctx, T::class.java) }) { init() }
}

inline fun <reified T : View> Activity.customView(@StyleRes theme: Int = 0, init: T.() -> Unit): T {
    return ankoView(theme, { ctx -> AnkoInternals.initiateView(ctx, T::class.java) }) { init() }
}
  • extending Views, Layouts like this:
inline fun Activity.verticalLayout(@StyleRes theme: Int = 0): LinearLayout = verticalLayout(theme, {})
inline fun Activity.verticalLayout(@StyleRes theme: Int = 0, init: _LinearLayout.() -> Unit): LinearLayout {
    return ankoView(theme, `$$Anko$Factories$CustomViews`.VERTICAL_LAYOUT_FACTORY, init)
}

inline fun ViewManager.appBarLayout(@StyleRes theme: Int): AppBarLayout = appBarLayout(theme, {})
inline fun ViewManager.appBarLayout(@StyleRes theme: Int, init: _AppBarLayout.() -> Unit): AppBarLayout {
    return ankoView(theme, `$$Anko$Factories$DesignViewGroup`.APP_BAR_LAYOUT) { init() }
}
@BennyWang
Copy link

+1

@fboldog fboldog mentioned this issue Mar 10, 2016
@yanex yanex added this to the Anko 0.9 milestone Mar 25, 2016
yanex added a commit that referenced this issue Apr 19, 2016
yanex added a commit that referenced this issue Apr 21, 2016
@yanex yanex added testing and removed open labels Apr 29, 2016
@dbacinski
Copy link

@yanex Is it ok? When do you plan to release Anko with this change?

@yanex yanex added fixed and removed testing labels May 31, 2016
@yanex yanex closed this as completed May 31, 2016
@mvysny
Copy link

mvysny commented Aug 8, 2016

Working great, thank you. What I'm missing though is the @StyleRes annotation on the theme parameter. This would warn user not to use the R.attr.* values by mistake.

@LouisCAD
Copy link

The README.md should be updated to reflect changes about this issue and #16 so we know how to use it.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants