首页 > 解决方案 > 访问 ANKO 布局组件内的 ANKO sqlite DB

问题描述

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

这是我的 ANKO 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())

这是使用 ANKO 布局组件的活动,组件应该使用按钮内的数据库。我已经在AnkoComponent's 代码中注释了,以指定。

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 定义在 com.example.jokegenerator 文件 Database.kt

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

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")
            }


        }
    }
}

标签: androidsqlitekotlinanko

解决方案


为什么不从 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()

推荐阅读