ButterKnife/findViewById 대신 Kotlin android extensions 사용하기
개인 광고 영역
Kotlin에서는 ButterKnife와 findViewById을 사용하지 않아도 됩니다.
Kotlin에서는 간단하게 kotlin Extensions을 사용할 수 있습니다.
우선 적용하지 않고 일반적인 코드는 아래와 같습니다.
findViewById를 매번 해야 하고, 귀찮습니다.
적용하는 방법도 여러 가지가 있을 수 있습니다.
class ImageFragment : Fragment(), ImageContract.View {
private val rootContainer by lazy {
activity.findViewById(R.id.root_container) as CoordinatorLayout
}
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
// 또는 아래와 같이
val rootContainer = activity.findViewById(R.id.root_container) as CoordinatorLayout
}
}
그래서 나온 것이 ButterKnife입니다. 아래와 같이 어노테이션을 이용하여 간단하게 사용이 가능합니다.
Data Binding을 쓰지 않는다면 ButterKnife이 아직은 최고라고 할 수 있습니다.
public class PhotoViewActivity extends AppCompatActivity {
@BindView(R.id.toolbar) Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ButterKnife 사용
ButterKnife.bind(this);
setSupportActionBar(toolbar);
}
}
Kotlin android extensions 적용하기
Kotlin을 메인 언어로 사용하는데 있어서 어떤 걸 쓰는 게 좋을까요?
data binding도 사용은 가능하고, findViewById로도 사용할 수 있습니다.
하지만 Kotlin에서는 아래와 같이 1줄만 추가해주면 extensions을 사용할 수 있는 kotlin-android-extensions이 제공됩니다.
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$rootProject.ext.kotlin_version"
}
당연히 kotlin 적용은 되어 있는 상태에서 활용이 가능합니다.
그리고 위에서 적용했던 코드에 android-extensions을 적용하면 아래와 같습니다.
그냥 layout에서 정의한 android:id="@+id/text"
를 직접 사용할 수 있습니다.
ButterKnife에서 적용했던 것처럼 ButterKnife.bind()
도 불필요하고, findViewById
도 불필요합니다.
그냥 바로 android:id="@+id/text"
의 text
를 통해 바로 접근할 수 이는 코드가 만들어집니다.
import kotlinx.android.synthetic.main.activity_image_sample.*
import kotlinx.android.synthetic.main.fragment_image_sample.*
class ImageFragment : Fragment(), ImageContract.View {
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
with (activity) {
root_container.visibility = View.GONE
}
recycler_image.visibility = View.GONE
}
}
하지만 이때 import
가 추가됩니다.
import kotlinx.android.synthetic.main.activity_image_sample.*
import kotlinx.android.synthetic.main.fragment_image_sample.*
import
에는 kotlinx.android.synthetic.main
까지는 공통으로 적용하고, 이후에는 layout
의 이름을 사용합니다.
레이아웃 이름이 activity_image_sample
이면 위와 같이 적용되고 끝에 .*
이 추가됩니다.
activity_image_sample에 포함하는 모든 데이터를 불러와서 쓸 수 있다는 말이 됩니다.
이는 자동으로 import 하게 됩니다.
하지만 모든 레이아웃이 이렇게 적용되면 좋겠지만 그렇지 않습니다.
그래서 적용하는 방법이 2가지 정도가 있습니다.
일반적으로는 with () {}
을 이용해서 처리가 가능합니다.
with 안에는 layout의 이름 또는 최상위 접근자를 추가해도 좋습니다.
예를 들면 아래와 같은 코드가 됩니다.
with (activity) {
root_container.visibility = View.GONE
}
만약 직접 만든 layout에 null 일 가능성이 있다면?
아래와 같이 작업해도 좋습니다.
activity?.apply {
root_container.visibility = View.GONE
}
이런 코드들은 알아서 findViewById을 생성해줍니다.
그만큼 편리하게 사용이 가능하지만 커스텀 뷰나 ViewHolder에서는 아래와 같은 코드를 함께 사용해야 해서 조금은 분편합니다.
with (itemView) {
root_container.visibility = View.GONE
}
// Null 발생을 대처하기 위해서 아래와 같이 사용한다
itemView?.run {
root_container.visibility = View.GONE
}
마무리
Kotlin에서는 ButterKnife는 필요하지 않습니다.
찾아보면 jakewharton이 작업했던 KotterKnife도 있긴 합니다.
하지만 Kotlin extensions이 있기에 초기에만 배포하고 이후에는 하지 않았습니다. kotlin extensions이 너무 편하기 때문이죠.
kotlin 적용 및 kotlin extensions만 적용하더라도 개발 속도를 향상시킬 수 있습니다.
감사합니다.
Comments