Migrate Fragment from Java to Kotlin
Use Kotlin View Binding to access view at onViewCreated
callback
---- which is called immediately after onCreateView()
has returned.
Otherwise crash IllegalStateException: view must not be null
will be happen if we use kotlin view binding before onViewCreated
.
Also, if Fragment is hosted in another fragment layout, then this fragment will be available at onViewCreated
.
<TextView
android:id="@+id/titleView"
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.detail_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// kotlin view binding allows us to assess the view by view id defined in the layout directly,
// instead of findViewById(R.id.xxx) or ButterKnife @BindView(R.id.xxx)
titleView.text = "title"
}
See Kotlin Android Extensions - View Binding: https://kotlinlang.org/docs/tutorials/android-plugin.html#view-binding
newInstance Pattern to create Fragment in Kotlin
Java static method in Fragment class:
public static ArticleDetailFragment newInstance(int articleId) {
Bundle args = new Bundle();
args.putInt(EXTRA_ARTICLE_ID, articleId);
ArticleDetailFragment fragment = new ArticleDetailFragment();
fragment.setArguments(args);
return fragment;
}
Kotlin static method:
可以使用 Companion object
:
Companion objects inside the class: a place for factory methods and static members, which can be accessed via class name.
companion object {
val EXTRA_ARTICLE_ID = "article_id"
fun newInstance(articleId: Int): ArticleDetailFragment {
val args = Bundle()
args.putInt(EXTRA_ARTICLE_ID, articleId)
val fragment = ArticleDetailFragment()
fragment.arguments = args
return fragment
}
}
也可以使用 Top level function
:
In most cases, it’s recommended that you use package-level functions. Top-level functions are compiled to static methods in the byte code. Link
从 Java 自动转 Kotlin 时,转换器很喜欢把Java里的get方法转成Kotlin里的val
Java:
private int getArticleId() {
if (getArguments() != null) {
return getArguments().getInt(EXTRA_ARTICLE_ID);
}
return -1;
}
Kotlin有2种形式,看似一样,实则不同:
// 调用时才被执行:
val articleId: Int
get() {
return if (arguments != null) arguments!!.getInt(EXTRA_ARTICLE_ID) else -1
}
// 类初始化时被执行,永远是-1:
val articleId: Int = if (arguments != null) arguments!!.getInt(EXTRA_ARTICLE_ID) else -1
但如果我们就是要通过get初始化一个值,运行时不会变化,Kotlin val显得更合适:
- public abstract int getLayout();
+ abstract val layout: Int
- override fun getLayout(): Int {
- return R.layout.article_detail_fragment
- }
+ override val layout: Int = R.layout.article_detail_fragment
2018-08-27 Weiyi Li