我在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
?
答案 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)
}
}
}
}