Giter Site home page Giter Site logo

Set style? about anko HOT 13 CLOSED

kotlin avatar kotlin commented on September 18, 2024
Set style?

from anko.

Comments (13)

mvysny avatar mvysny commented on September 18, 2024 3

Works great, thanks! If you wish to resolve attr value from Activity theme to style resource, just use this code:

val View.contextThemeWrapper: ContextThemeWrapper
get() = context.contextThemeWrapper

val Context.contextThemeWrapper: ContextThemeWrapper
get() = when (this) {
    is ContextThemeWrapper -> this
    is ContextWrapper -> baseContext.contextThemeWrapper
    else -> throw IllegalStateException("Context is not an Activity, can't get theme: $this")
}

@StyleRes
fun View.attrStyle(@AttrRes attrColor: Int): Int = contextThemeWrapper.attrStyle(attrColor)
@StyleRes
private fun ContextThemeWrapper.attrStyle(@AttrRes attrRes: Int): Int =
        attr(attrRes) {
            it.getResourceId(0, 0)
        }

private fun <R> ContextThemeWrapper.attr(@AttrRes attrRes: Int, block: (TypedArray)->R): R {
    val typedValue = TypedValue();
    if (!theme.resolveAttribute(attrRes, typedValue, true)) throw IllegalArgumentException("$attrRes is not resolvable")
    val a = obtainStyledAttributes(typedValue.data, intArrayOf(attrRes));
    val result = block(a)
    a.recycle()
    return result
}

then,

textView(attrStyle(R.attr.my_title)) {
}

from anko.

hannesstruss avatar hannesstruss commented on September 18, 2024 2

Resolving the attr does not actually work in all cases. Example:

button("My Button", theme = attrStyle(R.attr.buttonBarButtonStyle))

will not apply the correct background, since the one-argument constructor of Button that Anko uses calls through to the three-argument constructor with a default value for int defStyleAttr which overrides the button background with the default.

While working in some cases, the theme support of Anko 0.9 is not a full replacement for the style XML attribute. Can we reopen this issue?

from anko.

dennislysenko avatar dennislysenko commented on September 18, 2024 1

Nevermind. I created this shim:

public inline fun ViewManager.styledButton(text: CharSequence?, styleRes: Int = 0, init: Button.() -> Unit): Button {
    return ankoView({ if (styleRes == 0) Button(it) else Button(ContextThemeWrapper(it, styleRes), null, 0) }) {
        init()
        setText(text)
    }
}

public fun ViewManager.styledButton(text: CharSequence?, styleRes: Int = 0): Button = styledButton(text, styleRes) {}

Works perfectly, I just call styledButton("text", R.style.MyStyle). Thanks @sfunke!

from anko.

simophin avatar simophin commented on September 18, 2024 1

Is there any way to set style? So now you can set theme for each widget, like AppTheme, AppTheme.Light, but what if you need to set individual styles, eg. Widget.Button, Widget.Button.Colored?

from anko.

yanex avatar yanex commented on September 18, 2024

Anko has a style() function, though traditional Android XML styles are unsupported now.
Android SDK does not provide a good way to set View styles in code out of the box, and we are trying to find a way to support it.

from anko.

sfunke avatar sfunke commented on September 18, 2024

Inspired by the default Anko textView extension methods, and after doing some research on how to set a theme to a view by code, I came up with the following extension methods, which work very well so far (can be applied to any view class):

public inline fun ViewManager.textView(text: CharSequence?, styleRes: Int = 0, init: TextView.() -> Unit): TextView {
    return ankoView({ if (styleRes == 0) TextView(it) else TextView(ContextThemeWrapper(it, styleRes), null, 0) }) {
        init()
        setText(text)
    }
}

public fun ViewManager.textView(text: CharSequence?, styleRes: Int = 0): TextView = textView(text, styleRes) {}

Key is, you have to use ContextThemeWrapper, and the 3 argument constructor of the passed view, see this link: http://stackoverflow.com/a/28613069/1128600

That allows to pass an XML style, and have it fully applied to the newly created view (not comparable to the crappy setTextAppearance method)

@yanex Would it make sense to consider this for potential adoption into the standard library?

from anko.

dennislysenko avatar dennislysenko commented on September 18, 2024

@sfunke, does this only work for styling the text in a TextView, or is it generalized to applying any style resource to any view (including things like padding, backgrounds, borders, etc.?)

from anko.

BennyWang avatar BennyWang commented on September 18, 2024

@sfunke I think

public inline fun ViewManager.AnyView(theme: Int = 0, init: TextView.() -> Unit): AnyView

is enough.

from anko.

fboldog avatar fboldog commented on September 18, 2024

#143
;)

from anko.

BennyWang avatar BennyWang commented on September 18, 2024

@fboldog +1

from anko.

gregschlom avatar gregschlom commented on September 18, 2024

@simophin depends on what version you're targeting. on API 21+, Google added a 4th parameter to all Views constructors allowing you to set the style resource: https://developer.android.com/reference/android/view/View.html#View(android.content.Context,%20android.util.AttributeSet,%20int,%20int)

So if you're only targeting devices running 21+, it's easy to make custom Anko views calling that constructor. If you want to target devices running below 21, you're out of luck. There's no (easy) way to set the style programmatically because it's all private APIs used by the XML layout inflater.

What we ended up doing was to create very small XML layout files containing just <Button style="@style/WhiteButton" /> and then instantiating that layout with Anko's include<Button>(R.layout.white_button)

from anko.

yanex avatar yanex commented on September 18, 2024

@hannesstruss I've created the new issue for this: #361.

I also mark this issue as "closed". If you have other problems with themed views, please feel free to create the new issues.

from anko.

ayinmursalin avatar ayinmursalin commented on September 18, 2024

now you can use horizontalProgressBar { }

so no need to set style horizontal to progressBar

from anko.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.