1. 使能viewBinding
build.gradle
android {
...
buildFeatures {
viewBinding true
}
}
2. 自动识别ViewBinding类
object BindingHelper {
// 缓存
private val CACHED_BINDING_METHODS = hashMapOf<Class<*>, Method>()
@Suppress("UNCHECKED_CAST")
fun <T> getBindingView(componentClazz: Class<*>, layoutInflater: LayoutInflater): T {
val method = getInflateMethod(componentClazz)
return method.invoke(null, layoutInflater) as T
}
private fun getInflateMethod(componentClazz: Class<*>): Method {
if (CACHED_BINDING_METHODS.contains(componentClazz)) {
return CACHED_BINDING_METHODS[componentClazz]!!
}
var genericSuperClass = componentClazz.genericSuperclass
var typeArguments: List<Class<*>>? = if (genericSuperClass is ParameterizedType)
genericSuperClass.actualTypeArguments.map { it as Class<*> }
else null
var superClazz = componentClazz.superclass
while (typeArguments == null || !typeArguments.any { it.interfaces.contains(ViewBinding::class.java) }) {
if (superClazz == Object::class.java || superClazz == Any::class.java) {
throw RuntimeException("class ${componentClazz.canonicalName} has No Typed Parameters!")
}
genericSuperClass = superClazz.genericSuperclass
typeArguments = if (genericSuperClass is ParameterizedType)
genericSuperClass.actualTypeArguments.map { it as Class<*> }
else null
superClazz = superClazz.superclass
}
val clazz = typeArguments.first { it.interfaces.contains(ViewBinding::class.java) }
val m = clazz.getMethod("inflate", LayoutInflater::class.java)
CACHED_BINDING_METHODS[componentClazz] = m
return m
}
}
3. Activity自动识别
abstract class BaseBindingActivity<T: ViewBinding> : AppCompatActivity() {
protected lateinit var binding: T
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = BindingHelper.getBindingView(javaClass, layoutInflater)
setContentView(binding.root)
}
}
Sample
class MainActivity : BaseBindingActivity<ActivityMainBinding>() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 直接使用binding
}
}
4. Fragment自动识别
abstract class BaseBindingFragment<T : ViewBinding> : Fragment() {
private var _binding: T? = null
protected val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = BindingHelper.getBindingView(javaClass, layoutInflater)
initView()
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
Sample
class HomeFragment : BaseBindingFragment<FragmentHomeBinding>() {
override fun initView() {
// 使用binding
}
}
5. 保留ViewBinding的inflate函数混淆
proguard-rules.pro
-keepclassmembers class com.example.app.databinding.** {
public static <methods>;
}