Kotlin:如何访问CustomView的Attrs

时间:2016-04-19 11:16:45

标签: android android-custom-view kotlin

我在Kotlin中创建了一个自定义视图,并希望访问它的属性资源。

以下是我的代码

class CustomCardView : FrameLayout {

    constructor(context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    init {
        LayoutInflater.from(context).inflate(R.layout.view_custom_card, this, true)

        if (attrs != null) {
            val a = context.obtainStyledAttributes(attrs, R.styleable.custom_card_view)
            if (a.hasValue(R.styleable.custom_card_view_command)) {
                var myString = a.getString(R.styleable.custom_card_view_command)
            }
        }
    }
}

请注意,这会在init函数的attrs中出错。我想知道如何访问attrs

4 个答案:

答案 0 :(得分:14)

您无法从init块访问辅助构造函数参数。但至少有两种方法可以实现类似的功能。

第一种方法是使用具有默认参数的单个主构造函数而不是多个辅助构造函数。在这种情况下,您必须将@JvmOverloads注释应用于构造函数,以使Kotlin生成三个不同的构造函数。

class CustomCardView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : FrameLayout {

  init {
    LayoutInflater.from(context).inflate(R.layout.view_custom_card, this, true)

    if (attrs != null) {
      val a = context.obtainStyledAttributes(attrs, R.styleable.custom_card_view)
      if (a.hasValue(R.styleable.custom_card_view_command)) {
        var myString = a.getString(R.styleable.custom_card_view_command)
      }
    }
  }
}

秒方法是两个链构造函数,并使用三个参数将init块内容移动到构造函数中。

class CustomCardView : FrameLayout {

  constructor(context: Context) :
      this(context, null)

  constructor(context: Context, attrs: AttributeSet) :
      this(context, attrs, 0)

  constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) :
      super(context, attrs, defStyleAttr) {

    LayoutInflater.from(context).inflate(R.layout.view_custom_card, this, true)

    if (attrs != null) {
      val a = context.obtainStyledAttributes(attrs, R.styleable.custom_card_view)
      if (a.hasValue(R.styleable.custom_card_view_command)) {
        var myString = a.getString(R.styleable.custom_card_view_command)
      }
    }
  }
}

答案 1 :(得分:2)

为什么不简单地跳过具有默认值的这些冗长的构造函数,并这样做:

fft(X,L)

答案 2 :(得分:0)

调整你的代码,我想你也可以做这样的事情:

import Foundation
import SQLClient

class RecipeViewModel{
var recipes = [Recipe]()

init(){
    getRecipeFromDB()
}

func getRecipeFromDB(){

    let client = SQLClient.sharedInstance() as! SQLClient

    client.connect("x.x.x.x", username: "xx", password: "xxx", database: "xxx") {
        success in
        client.execute("SELECT item FROM TABLE") {
            results in

            for table in results as! [[[String:AnyObject]]] {
                for row in table {

                    for (columnName, value) in row {
                        let recipe = Recipe(code: value as! String, title: "Title")
                        recipes.append(recipe)
                        }
                    }
                }
// prints all recipes. Everything is perfect

        for i in self.recipes{
            print(i.code)
        }
            client.disconnect()
        }
//prints nothing. recipe.count = 0

        for i in self.recipes{
            print(i.code)
        }
    }
}

func error(error: String!, code: Int32, severity: Int32) {
    print(error)
    }
}

答案 3 :(得分:0)

这有点冗长,但是应该在所有情况下都能正常工作:

import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout

class CustomCardView: FrameLayout {

    constructor(context: Context) : super(context) {
        initialize(context, null)
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        initialize(context, attrs)
    }

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        initialize(context, attrs)
    }

    private fun initialize(context: Context, attrs: AttributeSet?) {
        LayoutInflater.from(context).inflate(R.layout.view_custom_card, this, true)

        attrs?.let {
            val a = context.obtainStyledAttributes(it, R.styleable.custom_card_view)
            if (a.hasValue(R.styleable.custom_card_view_command)) {
                var myString = a.getString(R.styleable.custom_card_view_command)
            }
        }
    }
}