问题
在全面抛弃xml使用anko的过程中,
发现尽管anko也支持使用include来引用一个公共的视图,
但如果该公共的视图也是使用anko来写的,
则会因为没有layout~id而不能引用~.
方案一
在特定的环境中写函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import org.jetbrains.anko._LinearLayout @SuppressLint("ResourceType") fun _LinearLayout.commonHeader() { toolbar { id = R.id.toolbar title = "shin system" } verticalLayout { id = R.id.user_frame textView("oo san") { id = R.id.user_name }
} }
|
然后就能在程序中有linearlayout的地方使用了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| class MainActivity : AppCompatActivity() { lateinit var mainUI: MainActivityUI
@SuppressLint("ResourceType") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState)
mainUI = MainActivityUI() mainUI.setContentView(this)
mainUI.txtView.text = "Hello World" mainUI.toolbar.title = "common3" } }
class MainActivityUI : AnkoComponent<MainActivity> {
lateinit var txtView: TextView lateinit var toolbar: Toolbar lateinit var userFrame: LinearLayout lateinit var userName: TextView
override fun createView(ui: AnkoContext<MainActivity>) = with(ui) { verticalLayout { commonHeader().also { toolbar = findViewById(R.id.toolbar) userFrame = findViewById(R.id.user_frame) userName = findViewById(R.id.user_name) } txtView = textView().apply { onClick { startActivity<SecondActivity>() } } } }
}
|
缺点:
- 需要依赖特定的环境,比如linearlayout
- 高度依赖id
方案二
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| fun ViewManager.commonHeader() = verticalLayout { toolbar { id = R.id.toolbar backgroundColor = ContextCompat.getColor(context, R.color.colorPrimary)
textView("shin system") { id = R.id.system_title textSize = sp(8).toFloat() }.lparams(wrapContent, wrapContent) { gravity = Gravity.CENTER_HORIZONTAL } }.lparams(width = matchParent)
verticalLayout { id = R.id.user_frame
textView("oo san") { id = R.id.user_name textSize = sp(6).toFloat() }.lparams(width = matchParent, height = wrapContent)
}.lparams(width = matchParent, height = wrapContent) }
|
使用方法同方案一,同时由于是函数,也不能分享内部对象到外部
改进
- 不再依赖特定环境,本身成为一种ViewGroup或者View,而不是之前的Unit类型
方案三
真正使用了自定义的component
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class CommonHeaderUI : AnkoComponent<Context> { lateinit var titleBar: Toolbar lateinit var titleText: TextView lateinit var userName: TextView
override fun createView(ui: AnkoContext<Context>): View = with(ui) { verticalLayout { titleBar = toolbar { backgroundColor = ContextCompat.getColor(context, R.color.colorPrimary)
titleText = textView("test app") { textSize = sp(8).toFloat() }.lparams(wrapContent, wrapContent) { gravity = Gravity.CENTER_HORIZONTAL } }.lparams(width = matchParent)
verticalLayout {
userName = textView("tony") { textSize = sp(6).toFloat() }.lparams(width = matchParent, height = wrapContent)
}.lparams(width = matchParent, height = wrapContent) } } }
|
使用时方法有变
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class MainActivityUI : AnkoComponent<MainActivity> {
var commonHeader = CommonHeaderUI() lateinit var txtView: TextView
override fun createView(ui: AnkoContext<MainActivity>) = with(ui) { verticalLayout { ankoView({ commonHeader.createView(AnkoContext.Companion.create(it)) }, 0, {})
txtView = textView().apply { onClick { startActivity<SecondActivity>() } } } } }
|
改进
- 可以分享内部的对象,无需使用id找