android - 在项目上使用自定义字体时数据绑定 MaterialTextView ClassCastException
问题描述
我在我的项目中使用数据绑定、MVVM 架构。
它以前工作得很好,但是当 Activity 尝试启动此布局时,应用程序突然崩溃。当我在项目的任何地方根本没有使用 MaterialTextView 时,它说com.google.android.material.textview.MaterialTextView 不能转换为com.github.ybq.android.spinkit.SpinKitView**。
我检查的东西
- 当我将行 app:visibleGone="@{viewModel.isLoading}" 移动到某个按钮时,这与 SpinKitViewLibrary 无关。它说 MaterialTextView 也不能转换为按钮。
- 我在这个项目中使用了相同的 visibleGone BindingAdapter 超过 10 个片段。它工作得很好。
- 当我删除 <variable name="viewModel" // 这部分是问题 1 type="com.junga.clabvoca.viewmodel.login.LoginViewModel" /> 布局没有崩溃
布局文件
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable
name="viewModel" // This part is problem 1
type="com.junga.clabvoca.viewmodel.login.LoginViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_login_main_1">
...
<com.junga.clabvoca.view.customview.CustomBasicButton
android:id="@+id/btn_naver_login"
android:layout_width="0dp"
android:layout_height="52dp"
app:backgroundTint="@color/naver_green"
app:layout_constraintBottom_toTopOf="@+id/btn_kakao_login"
app:layout_constraintEnd_toEndOf="@id/v_right"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@id/v_left"
app:text="네이버로 로그인"
app:textColor="@color/white"
android:layout_marginBottom="9dp" />
<com.github.ybq.android.spinkit.SpinKitView
android:id="@+id/hi"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
app:visibleGone="@{viewModel.isLoading}" **// This part is problem 2**
app:SpinKit_Color="?android:colorAccent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/v_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="@integer/guideline_small_v_left" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
活动文件
类登录活动:AppCompatActivity(),View.OnClickListener {
lateinit var binding: ActivityLoginBinding
lateinit var mOAuthLoginModule : OAuthLogin
lateinit var viewModel : LoginViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(LoginViewModel::class.java)
binding = DataBindingUtil.setContentView(this,R.layout.activity_login) // Error occurs here
binding.viewModel = viewModel
binding.lifecycleOwner = this
绑定适配器
@BindingAdapter("app:visibleGone")
fun showHide(view: View, show: Boolean) {
Logger.log("app visible gone : $show")
try{
view.setVisibility(if (show) View.VISIBLE else View.GONE)
}catch (e : Exception){
e.printStackTrace()
Logger.error(e.stackTrace.toString())
}
}
错误堆栈跟踪
2021-04-14 19:33:11.493 7794-7794/com.junga.clabvoca W/System.err: java.lang.ClassCastException: com.google.android.material.textview.MaterialTextView 无法转换为com.github.ybq.android.spinkit.SpinKitView 2021-04-14 19:33:11.493 7794-7794/com.junga.clabvoca W/System.err:在 com.junga.clabvoca.databinding.ActivityLoginBindingImpl.(ActivityLoginBindingImpl. java:38) 2021-04-14 19:33:11.493 7794-7794/com.junga.clabvoca W/System.err: 在 com.junga.clabvoca.databinding.ActivityLoginBindingImpl.(ActivityLoginBindingImpl.java:35) 2021-04 -14 19:33:11.493 7794-7794/com.junga.clabvoca W/System.err: 在 com.junga.clabvoca.DataBinderMapperImpl.getDataBinder(DataBinderMapperImpl.java:188) 2021-04-14 19:33:11.493 7794 -7794/com.junga.clabvoca W/System.err:在 androidx.databinding.MergedDataBinderMapper.getDataBinder(MergedDataBinderMapper.java:74)
登录视图模型
class LoginViewModel : ViewModel() {
val mRepo = LogInRepository()
val postLoginResponse = mRepo.postLoginResponse
val isLoading = MutableLiveData(false)
val isWhat = MutableLiveData(false)
fun isLoading(flag : Boolean) {
isLoading.value = flag
}
fun getPostLoginResponse() : LiveData<Resource<PostLoginResponse>> = postLoginResponse
fun postLogin(postData : PostLogin){
mRepo.postLogin(postData)
}
val getUserResponse = mRepo.getUserResopnse
fun getGetUserResponse(): LiveData<Resource<GetUserResponse>> = getUserResponse
fun getUser(){
mRepo.getUser()
}
}
这可能是由我在活动中实现 viewModel 和数据绑定的方式引起的吗?我被困住了:(
21.04.14 更新
我以某种方式解决了这个问题,但我仍然不知道为什么它不起作用。所以我有一个绑定适配器,可以根据用户选择的主题转换字体。bindin 适配器看起来像这样
@BindingAdapter("app:setFont")
fun setTextStyle(view: TextView, type : String){
try {
Logger.log("set text style")
if(AppPreferences.font == 0){
when(type){
"regular" -> {
view.typeface = ResourcesCompat.getFont(context, FontTypes.REGULAR_1.fontRes)
}
"medium" -> {
view.typeface = ResourcesCompat.getFont(context, FontTypes.MEDIUM_1.fontRes)
}
"bold" -> {
view.typeface = ResourcesCompat.getFont(context, FontTypes.BOLD_1.fontRes)
}
}
}else if(AppPreferences.font == 1){
when(type){
"regular", "medium" -> {
view.typeface = ResourcesCompat.getFont(context, FontTypes.MEDIUM_2.fontRes)
}
"bold" -> {
view.typeface = ResourcesCompat.getFont(context, FontTypes.BOLD_2.fontRes)
}
}
}else {
when(type){
"regular", "medium" -> {
view.typeface = ResourcesCompat.getFont(context, FontTypes.MEDIUM_3.fontRes)
}
"bold" -> {
view.typeface = ResourcesCompat.getFont(context, FontTypes.BOLD_3.fontRes)
}
}
}
}catch (e :Exception){
}
}
当我没有在设置样式属性的文本视图上设置绑定适配器值时,就会发生错误。
<TextView
android:id="@+id/logo_text"
style="@style/Header2.Bold.White"
app:setFont="@{@string/bold}" // without line this occur error
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/logo_text"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@+id/logo_bottom"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
但是没有 style 属性,不使用 app:setFont 属性是可以的。
所以问题是每当我在 textview 上使用样式 attr 时,我都需要设置 setFont。这是非常奇怪的行为,我想知道为什么。
解决方案
将功能更改为静态。
companion object {
@JvmStatic
@BindingAdapter("app:setFont")
fun setTextStyle(view: TextView, type : String) {
...
}
}
推荐阅读
- javascript - 为什么 $q.all(promises).then() 不等待承诺?
- php - 如何遍历已转换为关联数组的json对象获取prop值
- django - 在我的 Django 项目中更改时重新加载 Celery
- microsoft-graph-api - 过滤 MS Graph Delta
- node.js - Node-Red 服务之间的调用以:RequestError: socket hang up 结尾
- accessibility - Microsoft Access 2016 和辅助功能
- python - 多处理星图返回列表而不是字典
- java - 如何使用 JPA/Hibernate 将“On Delete Cascade”添加到加入表
- c# - 带有 XAML WPF 的 Powershell 动态运行命令
- node.js - windows10和windows server 2012 nodejs在请求数据中捕获意外令牌