在 ANKO 布局组件中访问 ANKO sqlite DB

access ANKO sqlite DB inside ANKO layout component

我想访问我的 AnkoComponent 中的 ANKO SQLite 数据库。但是,我收到组件范围内的错误提示,并且在 activity 中使用 AnkoComponent 它工作得很好。

这是我的安口SQLite数据库

package com.example.jokegenerator

import android.content.Context
import android.database.sqlite.SQLiteDatabase
import org.jetbrains.anko.db.*

class DatabaseOpenHelper(context: Context) :
        ManagedSQLiteOpenHelper(context, "Database", null, 2) {


    companion object {
        private var instance: DatabaseOpenHelper? = null

        @Synchronized
        fun getInstance(ctx: Context): DatabaseOpenHelper {
            if (instance == null) {
                instance = DatabaseOpenHelper(ctx.getApplicationContext())
            }
            return instance!!
        }
    }

    override fun onCreate(db: SQLiteDatabase) {
        // Here you create tables
        db.createTable("Jokes", true,
            "id" to INTEGER + PRIMARY_KEY + UNIQUE,
            "joke" to TEXT)
        db.insert("Jokes",
            "joke" to "Humor is not for everyone")
    }

    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        db.dropTable("User", true)
    }
}

val Context.database: DatabaseOpenHelper
    get() = DatabaseOpenHelper.getInstance(getApplicationContext())

这是activity使用ANKO布局组件的地方,组件应该使用按钮里面的数据库。我已经在 AnkoComponent 的代码中进行了评论,以指定。

class JokeActivityUI : AnkoComponent<JokeActivity> {

    override fun createView(ui: AnkoContext<JokeActivity>) = with(ui) {
        verticalLayout {
            textView {

            }.lparams(width = matchParent) {

            }
            var getRndJoke = button {
                text = "get random joke!"


                onClick {
                    database.use{ //prompted with error written below!

                    }


                }
            }.lparams(width = matchParent) {

            }
            button {
                text = "create a joke"
                onClick {
                    startActivity<CreateJokeActivity>()
                }
            }.lparams(width = matchParent) {

            }
            button {
                text = "frontpage"
                onClick {
                    startActivity<MainActivity>()
                }
            }.lparams(width = matchParent) {

            }
        }
    }
}

但是我收到一条错误消息提示:

public val Context.database: DatabaseOpenHelper defined in com.example.jokegenerator in file Database.kt

但是在 activity 使用布局的内部我可以很好地使用数据库

class JokeActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        JokeActivityUI().setContentView(this)


        database.use { //works just fine in this scope
            val dbJokes = database.use {
                select("Jokes")
            }


        }
    }
}

为什么不从 Activity 访问它?我认为最好让 UI 只关注 UI。

首先,在 JokeActivityUI 中创建名为 getRndJoke

的 lateinit var
class JokeActivityUI : AnkoComponent<JokeActivity> {

     lateinit var getRndJoke: Button

     ...
}

然后将变量 getRndJoke 分配给按钮

getRndJoke = button {
   text = "get random joke!"
}.lparams(width = matchParent)

因此,您可以像这样轻松访问 Activity 中的数据库:

class JokeActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        JokeActivityUI().setContentView(this)

        JokeActivityUI().getRndJoke.onClick {

           database.use {
              ...
           }
        }
    }
}

额外:我认为最好像这样创建实例 JokeActivityUI:

val ui = JokeActivityUI()