• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Android ViewBinding类型参数自动加载Activity/Fragment

武飞扬头像
_Lulixue_
帮助1

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>;
}

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhhaakha
系列文章
更多 icon
同类精品
更多 icon
继续加载