Kotlin Android Extensions是Kotlin团队开发的一个插件目的是让我们在开发过程中更少的编写代码。目前包括了视图绑定的功能。
几种绑定视图方式对比
- xml文件如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:gravity="center"
>
<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录"
/>
</LinearLayout>
- 第一种传统方式绑定视图findViewById
private lateinit var mLoginBtn:Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mLoginBtn = findViewById(R.id.btn_login) as Button
mLoginBtn.setOnClickListener {
Toast.makeText(this@MainActivity,"登录",Toast.LENGTH_SHORT).show()
}
}
在这种方式里面一般情况下我们会定义一个成员变量来接收视图同时使用findViewById并做一次类型转换。
- 第二种框架注解绑定视图ButterKnife
/*
引入编译插件和依赖包。略过...
*/
@BindView(R.id.btn_login)
lateinit var mLoginBtn:Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
ButterKnife.bind(this)
mLoginBtn.setOnClickListener {
Toast.makeText(this@MainActivity,"登录",Toast.LENGTH_SHORT).show()
}
}
可以看到使用ButterKnife不但要引入它的编译插件和库文件在绑定视图的过程中依然需要定义成员变量代码量并没有减少。
- 第三种插件绑定视图Kotlin-Android-Extensions
1、在Module中的build.gradle文件添加插件配置
apply plugin: 'kotlin-android-extensions'
2、在需要绑定视图的Activity、Fragment、Adapter及自定义View中引入资源文件
import kotlinx.android.synthetic.main.activity_main.*
3、 在使用的位置直接使用xml中对应的id访问视图完整代码如下
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn_login.setOnClickListener {
Toast.makeText(this@MainActivity,"登录",Toast.LENGTH_SHORT).show()
}
}
}
引入文件详细说明
import kotlinx.android.synthetic.main.activity_main.*
- 固定前缀import kotlinx.android.synthetic.main
- 布局文件名称activity_main
- 需要引入的视图“”表示引入布局下所有视图当然也可以只引入需要的视图把换成对应的id就行啦如下:
import kotlinx.android.synthetic.main.activity_main.btn_login
- 在Adapter和自定义View中引入需要在布局文件名后添加view节点如下
import kotlinx.android.synthetic.main.view_login.view.*
Kotlin插件绑定视图范围
- 在Activity中使用引入资源文件直接使用id访问视图
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn_login.setOnClickListener {
Toast.makeText(this@MainActivity,"登录",Toast.LENGTH_SHORT).show()
}
}
}
- 在Fragment中使用引入资源文件直接使用id访问视图
有一点特别注意在onCreateView中不直接访问视图因为视图没有加载完成容易引起空指针需要在onViewCreated中访问视图代码如下
import kotlinx.android.synthetic.main.view_login.*
class LoginFragment:Fragment() {
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
return inflater?.inflate(R.layout.view_login, container, false)
}
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btn_login.setOnClickListener {
Toast.makeText(context,"登录", Toast.LENGTH_SHORT).show()
}
}
}
- 在Adapter中使用引入布局文件需要添加view节点可使用ViewHolder中的itemView直接访问视图当然也可以在ViewHolder中做一次视图绑定与传统ViewHolder类似代码如下
import kotlinx.android.synthetic.main.view_login.view.*
class LoginAdapter(var context: Context):RecyclerView.Adapter<LoginAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
val view = LayoutInflater.from(context)
.inflate(R.layout.view_login,parent,false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.itemView.btn_login.setOnClickListener {
Toast.makeText(context,"登录", Toast.LENGTH_SHORT).show()
}
}
override fun getItemCount(): Int {
return 3
}
class ViewHolder(view: View) : RecyclerView.ViewHolder(view)
}
- 在自定义View中使用引入布局文件需要添加view节点在自定义视图中可直接使用id访问视图代码如下
import kotlinx.android.synthetic.main.view_login.view.*
class LoginView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
init {
View.inflate(context,R.layout.view_login,this)
btn_login.setOnClickListener {
Toast.makeText(context,"登录", Toast.LENGTH_SHORT).show()
}
}
}
···········································
欢迎关注课程
Kotlin打造完整电商APP 模块化+MVP+主流框架