【问题标题】:Why is createView never called?为什么从不调用 createView?
【发布时间】:2017-11-13 00:15:31
【问题描述】:

我的最终目标是能够将我的内容小部件移动到自定义视图中,并在我的 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)
}

【问题讨论】:

    标签: kotlin anko


    【解决方案1】:

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

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

    这里是解决方案的一些关键部分,我还创建了一个带有完整代码的Gist

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

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

    在主视图中,我有字段来引用“子视图”中的小部件,然后我在传递给 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
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-14
      • 2020-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 2019-03-08
      • 2010-12-13
      • 2019-11-22
      相关资源
      最近更新 更多