AtomicStrongForce
AtomicStrongForce

Reputation: 721

Setting padding programmatically and through xml

I'm creating some custom components and I would like to have a default padding set, but also be able to configure it through xml if so desired.

For example:

Simple custom TextView component with default padding:

class MyComponent @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : TextView(context, attrs, defStyle) {

init {
        layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)

        val verticalPadding = resources.getDimension(R.dimen.FourDp).toInt()
        val horizontalPadding = resources.getDimension(R.dimen.FourDp).toInt()
        setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding)
    }
}

This component would then be dropped into the app as:

<com.example.components.MyComponent
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="padding test"
                    <!-- setting padding is optional --> 
                    android:paddingTop="32dp"/>

The Question

Android currently ignores the 32dp of padding set through xml and goes with the four dp of padding that's in the component's init method. Is there a way that I can get Android to use the padding set in xml if it exists, and use the default padding if no such padding is specified in xml?

Upvotes: 0

Views: 1299

Answers (1)

pt2121
pt2121

Reputation: 11880

You can use obtainStyledAttributes to retrieve XML attributes and hasValue to check if there is an attribute at index.

init {
  layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)

  val verticalPadding = resources.getDimension(R.dimen.FourDp).toInt()
  val horizontalPadding = resources.getDimension(R.dimen.FourDp).toInt()

  val attributes = intArrayOf(android.R.attr.paddingLeft, android.R.attr.paddingTop,
      android.R.attr.paddingBottom, android.R.attr.paddingRight)

  val arr = context.obtainStyledAttributes(attrs, attributes)

  // determine if paddingTop is set if not, use verticalPadding 
  val paddingRight = if (arr.hasValue(android.R.attr.paddingTop))
    arr.getDimensionPixelOffset(android.R.attr.paddingTop, -1)
  else
    verticalPadding

  // setPadding

  arr.recycle()
}

Upvotes: 1

Related Questions