Bryanx / themed-toggle-button-group

Customisable toggle buttons inside a FlexboxLayout.
MIT License
747 stars 46 forks source link

Set programmatically toggle's margin size and text size #17

Open Aleclock opened 3 years ago

Aleclock commented 3 years ago

Is it possibile to add programmatically toggle's attributes like toggle_textSize and margin? I can’t find a solution

Bryanx commented 3 years ago

Yeah you can

Change textSize:

ThemedButton.applyToTexts { it.textSize = 20F }

Change margins of individual button:

val params = RelativeLayout.LayoutParams(WRAP_CONTENT, MATCH_PARENT)
params.setMargins(20,10,20,10)
ThemedToggleButtonGroup.addView(btn, params)

You can also specify margins between all buttons:

ThemedToggleButtonGroup.horizontalSpacing = 50

Also I usually create an extension method like this:

fun View.setMargin(leftMargin: Int? = null, topMargin: Int? = null,
                   rightMargin: Int? = null, bottomMargin: Int? = null) {
    val params = layoutParams as ViewGroup.MarginLayoutParams
    params.setMargins(
        leftMargin ?: params.leftMargin,
        topMargin ?: params.topMargin,
        rightMargin ?: params.rightMargin,
        bottomMargin ?: params.bottomMargin)
    layoutParams = params
}
//And use it like this:
ThemedButton.setMargin(rightMargin = 20)
Aleclock commented 3 years ago

Thanks for the quickly response.

I'm trying to add programmatically several toggles but if I set a fixed height (instead of WRAP_CONTENT) the text is not vertically centered.

I created in the XML layout a ThemedToggleButtonGroup with a reference toggle

<nl.bryanderidder.themedtogglebuttongroup.ThemedToggleButtonGroup
            android:id="@+id/item_detail_toggle_group"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:toggle_requiredAmount="0"
            app:flexWrap="wrap">

            <nl.bryanderidder.themedtogglebuttongroup.ThemedButton
                android:layout_width="wrap_content"
                android:layout_height="30dp"
                app:toggle_textSize="12dp"/>

(I removed graphic attributes like borderWidth, borderColor and background)

In my activity i created each toggle with

val toggleButton = ThemedButton(window.context)
toggleButton.setPadding(0,0,0,0)
toggleButton.applyToTexts { it.textSize = 12f }
toggleButton.gravity = Gravity.CENTER_VERTICAL

Then I add toggle to ThemedToggleButtonGroup

//val params = ConstraintLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
val params = ConstraintLayout.LayoutParams(WRAP_CONTENT, 90)
params.setMargins(5,5,5,5)
item_detail_toggle_group.addView(toggleButton, params)

where 90 is equal to 30dp

This is the result i get: when I set ConstraintLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT) [2] text is vertically centered, but when I set ConstraintLayout.LayoutParams(WRAP_CONTENT, 90) [1] text is partially cut and not centered.

toggle_problem

Bryanx commented 3 years ago

I don't have an ideal solution for this. The text is cut off because of the standard padding on the text. You can use a typical extension function for padding, I will consider adding these functions to the library if more people require this:

// extension function for padding
fun View.setViewPadding(
    left: Float? = null, top: Float? = null,
    right: Float? = null, bottom: Float? = null,
    horizontal: Float? = null, vertical: Float? = null,
    all: Float? = null
) {
    if (listOfNotNull(left, top, right, bottom, horizontal, vertical, all).any { it < 0f }) return
    all?.let { setPadding(it.toInt(), it.toInt(), it.toInt(), it.toInt()) }
    horizontal?.let { setPadding(paddingLeft, it.toInt(), paddingRight, it.toInt()) }
    vertical?.let { setPadding(it.toInt(), paddingTop, it.toInt(), paddingBottom) }
    setPadding(
        left?.toInt() ?: paddingLeft,
        top?.toInt() ?: paddingTop,
        right?.toInt() ?: paddingRight,
        bottom?.toInt() ?: paddingBottom
    )
}

// extension property for layout gravity
var View.layoutGravity
    get() = (layoutParams as FrameLayout.LayoutParams).gravity
    set(value) {
        layoutParams = FrameLayout.LayoutParams(
            layoutParams.width,
            layoutParams.height,
            value
        )
    }

After adding these extension functions:

buttonGroup.buttons.forEach {
    it.applyToTexts { text ->
        text.textSize = 12f
        text.setViewPadding(all = 0f)
        text.layoutGravity = Gravity.CENTER_VERTICAL
    }
}
Aleclock commented 3 years ago

Thanks a lot, it worked! Much appreciated

Bryanx commented 3 years ago

I will reopen this as I think this could be implemented more user-friendly and current solution may be a bit unintuitive.

hdwipa commented 2 years ago

i am facing this issue on my project. thanks for the solution above