Sobes.tech
Middle

How to get rid of four constructors in a custom view (CustomView)?

sobes.tech AI

Answer from AI

You can use the factory method or builder pattern instead of directly using constructors.

  • Factory Method: Allows creating view instances by abstracting the creation process and hiding the logic of choosing the appropriate constructor.

    class MyCustomView private constructor(
        context: Context,
        attrs: AttributeSet?,
        defStyleAttr: Int,
        defStyleRes: Int
    ) : View(context, attrs, defStyleAttr, defStyleRes) {
    
        // Private constructor to enforce the use of factory methods
    
        companion object {
            fun createDefault(context: Context): MyCustomView {
                // Initialization logic for the default constructor
                return MyCustomView(context, null, 0, 0)
            }
    
            fun createFromAttrs(context: Context, attrs: AttributeSet?): MyCustomView {
                // Initialization logic with attributes
                return MyCustomView(context, attrs, 0, 0)
            }
    
            // Additional factory methods for other constructor combinations
        }
    }
    
  • Builder pattern: Useful when there are many constructors or they have numerous optional parameters. It allows step-by-step creation of the view object.

    class MyCustomView private constructor(
        private val context: Context,
        private val attrs: AttributeSet?,
        private val defStyleAttr: Int,
        private val defStyleRes: Int
    ) : View(context, attrs, defStyleAttr, defStyleRes) {
    
        // Private constructor
    
        class Builder(private val context: Context) {
            private var attrs: AttributeSet? = null
            private var defStyleAttr: Int = 0
            private var defStyleRes: Int = 0
    
            fun setAttrs(attrs: AttributeSet?) = apply { this.attrs = attrs }
            fun setDefStyleAttr(defStyleAttr: Int) = apply { this.defStyleAttr = defStyleAttr }
            fun setDefStyleRes(defStyleRes: Int) = apply { this.defStyleRes = defStyleRes }
    
            fun build(): MyCustomView {
                // Logic for creating and initializing the view based on parameters
                return MyCustomView(context, attrs, defStyleAttr, defStyleRes)
            }
        }
    }
    
    // Using Builder
    val myView = MyCustomView.Builder(context)
        .setAttrs(attrs)
        .build()
    

The choice between factory method and builder pattern depends on the complexity of view initialization. For simpler cases, factory methods suffice. For more complex scenarios with many options, the builder is preferable.