作为Android研发,findViewById代码想必每个人都不默认。虽然现在有不少工具可以减少这块的工作量,例如:
- DataBinding 可以免除findViewById【貌似国内用的很少】;
- ButterKnife 配合Zelezny插件也可以自动生成BindView代码
- 项目大了,基于编译器根据注解生成代码的方式,很容易拖累打包速度。
- 其次,非application module,需要使用R2,要小心import,偶尔和R.class对应错了,会出现看起来很奇怪的问题。
- 我司已经放弃ButterKnife了,改为手动findViewById了,对现在的平台型复杂工程来说,手动findViewById其实不算是问题;
- Kotlin因为比较灵活的语法,也有不少解决方案,例如 Jetpack Compose【至少目前还不够成熟和普及】。
因此,偶尔或者经常,需要手写一些findViewById
代码,刚好,这也是脚本可以大显身手的领域。脚本如下,已经写好,需要的同学自取。(使用awk
)
生成代码效果:
LottieAnimationView mAnimationLottieView; // 开奖中动画
com.facebook.drawee.view.SimpleDraweeView mMissAnimationView; // 开奖结果动画:未中奖
com.facebook.drawee.view.SimpleDraweeView mLuckyAnimationView; // 开奖结果动画:
RelativeLayout mStarContentAreaView;
com.yxcorp.gifshow.image.KwaiImageView mStarBackgroundView; // 背景图
View mTipsHostView;
ImageView mCloseImageView;
TextView mStatusTextView;
TextView mTipTextView;
androidx.recyclerview.widget.RecyclerView mUserRecyclerView;
TextView mDataTextView;
RelativeLayout mResultRootView;
public void doBindView(View rootView) {
mDialogContentLayout = rootView.findViewById(R.id.xxx);
mAnimationLottieView = rootView.findViewById(R.id.xxx);
mMissAnimationView = rootView.findViewById(R.id.xxx);
mLuckyAnimationView = rootView.findViewById(R.id.xxx);
mStarContentAreaView = rootView.findViewById(R.id.xxx);
mStarBackgroundView = rootView.findViewById(R.id.xxx);
mTipsHostView = rootView.findViewById(R.id.xxx);
mCloseImageView = rootView.findViewById(R.id.xxx);
mStatusTextView = rootView.findViewById(R.id.xxx);
mTipTextView = rootView.findViewById(R.id.xxx);
mUserRecyclerView = rootView.findViewById(R.id.xxx);
mDataTextView = rootView.findViewById(R.id.xxx);
mResultRootView = rootView.findViewById(R.id.xxx);
}
#! /usr/bin/env awk -f
function _title(name) {
l = length(name)
return toupper(substr(name, 1, 1))""tolower(substr(name, 2, l-1))
}
function _id2name(id) {
len = split(id, arr, "_")
r = "m"
for (i = len - 2; i <= len; i++) {
r = r""_title(arr[i])
}
if (!match(r, "(View|Button|Layout)$")) {
r = r"View"
}
return r
}
function _append_code(segment) {
code = code""segment"\n"
}
function _get_comment(key) {
if (key in comments) {
return " // "comments[key]
}
return ""
}
BEGIN {
i = 1
}
/<!--.*-->/ {
split($1, arr, "--")
cm = arr[2]
}
/<[a-zA-Z0-9$_.]+/ {
view = substr($1, 2, length($1) - 1);
}
/android:id="@\+id\// {
split($1, arr, "=");
id = substr(arr[2], 7, length(arr[2]) - 7);
if (length(cm) > 0) {
comments[i] = cm
cm = ""
}
views[i] = view
ids[i] = id
i = i + 1
}
END {
code=""
for (j in views) {
_append_code(sprintf("%s %s;%s", views[j], _id2name(ids[j]), _get_comment(j)))
}
_append_code("")
_append_code("public void doBindView(View rootView) {")
for (j in views) {
_append_code(sprintf("\t%s = rootView.findViewById(R.id.%s);", _id2name(ids[j]), ids[j]))
}
_append_code("}")
print code
}