为什么从未调用createView?

时间:2017-11-13 00:15:31

标签: kotlin anko

我的最终目标是能够将我的内容小部件移动到自定义视图中,并在MainView中的Anko布局中实例化该视图。我以为我有一点工作,但我不能重现它。

当我使用以下代码运行时,MainContextView的createView中的内容永远不会显示,我从未看到消息“创建主要上下文视图”,但我执行请参阅消息“主要内容视图”。

我首先创建一个MainContextView

class MainContextView(context: Context) : ViewGroup(context), AnkoComponent<Context> {

    lateinit var textBox: EditText
    lateinit var button: Button
    lateinit var clickCount: TextView

    override fun createView(ui: AnkoContext<Context>) = with(ui) {
        println("creating main context view")
        verticalLayout {
            themedEditText {
                hint = "hi from main context"
            }
            button = themedButton {
                text = "ok"
            }
            textBox = themedEditText {
                hint = "hi"
            }
            clickCount = themedTextView {
               text = "0"
            }
        }
    }

    override fun onLayout(p0: Boolean, p1: Int, p2: Int, p3: Int, p4: Int) {
        println("onLayout called")
    }

}

并从我的主视图中调用它

class MainView : AnkoComponent<MainActivity> {

    lateinit var mainCtx: MainContextView
    lateinit var textBox: EditText
    lateinit var button: Button
    lateinit var clickCount: TextView
    lateinit var mainMenu: Menu
    lateinit var settingItem: MenuItem
    lateinit var otherItem: MenuItem
    lateinit var floatingActionButton: FloatingActionButton

    override fun createView(ui: AnkoContext<MainActivity>) = with(ui) {
        coordinatorLayout {
            verticalLayout {
                themedAppBarLayout {
                    themedToolbar(theme = R.style.Base_ThemeOverlay_AppCompat_Dark_ActionBar) {
                        title = resources.getString(R.string.app_name)
                        popupTheme = R.style.AppTheme
                        mainMenu = menu
                        settingItem = mainMenu.add("My Settings")
                        otherItem = mainMenu.add("My Other")
                    }
                }.lparams(width = matchParent, height = wrapContent)

                // ************************************
                // HERE IS THE CALL TO THE CONTEXT VIEW
                mainCtx = mainContextView { println("main content view ") }
               // *************************************

            }.lparams(width = matchParent, height = wrapContent) {
            }
            floatingActionButton = floatingActionButton {
                imageResource = android.R.drawable.ic_dialog_email
            }.lparams {
                margin = dip(10)
                gravity = Gravity.BOTTOM or Gravity.END
            }
        }
    }
}

MainView被称为设置为MainActivity的内容视图

class MainActivity : AppCompatActivity() {

    private lateinit var presenter: MainPresenter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val mainView = MainView()
        mainView.setContentView(this)
        presenter = MainPresenter(mainView)

    }

}

最后是ViewManger扩展

inline fun ViewManager.mainContextView(theme: Int = 0) = mainContextView(theme) {}

inline fun ViewManager.mainContextView(theme: Int = 0, init: MainContextView.() -> Unit): MainContextView {
    return ankoView({ MainContextView(it) }, theme, init)
}

1 个答案:

答案 0 :(得分:1)

我发现了我的问题,它与我的subView被定义为View / ViewGroup的子类有关,但并没有真正实现任何方法。

事实证明这不是正确的方向。该解决方案基于对此issue

的评论

以下是解决方案的一些关键部分,我还使用完整代码创建了Gist

扩展功能,创建“SubView”类的实例,然后在createView()方法中调用ankoView()方法。它还将创建的实例传递给传递给扩展函数的闭包,这是关键,因为它允许访问视图中包含的小部件。

inline fun ViewManager.mainContentView(theme: Int = 0) = mainContentView(theme) {}

inline fun ViewManager.mainContentView(theme: Int = 0, init: View.(mainContentView: MainContentView) -> Unit): View {
    val mainContentView = MainContentView()
    return ankoView({ mainContentView.createView(AnkoContext.create(it)) }, theme, { init(mainContentView)} )
}

“内容视图”创建布局并保存对小部件的引用。

class MainContentView :  AnkoComponent<Context> {

    lateinit var textBox: EditText
    lateinit var button: Button
    lateinit var clickCount: TextView

    override fun createView(ui: AnkoContext<Context>) = with(ui) {
        verticalLayout {
            button = themedButton {
                text = "ok"
            }
            textBox = themedEditText {
                hint = "hi"
            }
            clickCount = themedTextView {
                text = "0"
            }
        }
    }
}

在主视图中,我有字段来引用“subView”中的小部件,然后我在传递给mainContentView实例的闭包中初始化。

lateinit var textBox: EditText
lateinit var button: Button
lateinit var clickCount: TextView
private lateinit var mainMenu: Menu
lateinit var settingItem: MenuItem
lateinit var otherItem: MenuItem
private lateinit var floatingActionButton: FloatingActionButton


override fun createView(ui: AnkoContext<MainActivity>) = with(ui) {
    coordinatorLayout {
        verticalLayout {
            themedAppBarLayout {
                themedToolbar(theme = R.style.Base_ThemeOverlay_AppCompat_Dark_ActionBar) {
                    title = resources.getString(R.string.app_name)
                    popupTheme = R.style.AppTheme
                    mainMenu = menu
                    settingItem = mainMenu.add("My Settings")
                    otherItem = mainMenu.add("My Other")
                }
            }.lparams(width = matchParent, height = wrapContent)
            mainContentView {
                button = it.button
                textBox = it.textBox
                clickCount = it.clickCount
            }.lparams(width = matchParent, height = wrapContent)
        }.lparams(width = matchParent, height = wrapContent)
        floatingActionButton = floatingActionButton {
            imageResource = android.R.drawable.ic_dialog_email
        }.lparams {
            margin = dip(10)
            gravity = Gravity.BOTTOM or Gravity.END
        }
    }
}
相关问题