为什么从不调用 createView?
Why is createView never called?
我的最终目标是能够将我的内容小部件移动到自定义视图中,并在我的 MainView 的 Anko 布局中实例化该视图。我以为我曾经有过这个工作,但我无法重现它。
当我 运行 使用以下代码时,MainContextView createView
中的内容从不显示,我也从未看到消息 "creating main context view",但我 做看到消息"main content view"。
我首先创建一个 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)
}
我发现了我的问题,它与我的子视图有关,它被定义为 View/ViewGroup 的子 class,但没有真正实现任何方法。
事实证明这并不是真正正确的方向。该解决方案基于对此 issue
的评论
下面是解决方案的一些关键部分,我还创建了一个包含完整代码的 Gist。
扩展函数,创建"SubView"实例class然后在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)} )
}
"content view" 创建布局并保存对小部件的引用。
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
}
}
}
我的最终目标是能够将我的内容小部件移动到自定义视图中,并在我的 MainView 的 Anko 布局中实例化该视图。我以为我曾经有过这个工作,但我无法重现它。
当我 运行 使用以下代码时,MainContextView createView
中的内容从不显示,我也从未看到消息 "creating main context view",但我 做看到消息"main content view"。
我首先创建一个 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)
}
我发现了我的问题,它与我的子视图有关,它被定义为 View/ViewGroup 的子 class,但没有真正实现任何方法。
事实证明这并不是真正正确的方向。该解决方案基于对此 issue
的评论下面是解决方案的一些关键部分,我还创建了一个包含完整代码的 Gist。
扩展函数,创建"SubView"实例class然后在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)} )
}
"content view" 创建布局并保存对小部件的引用。
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
}
}
}