首页 > 解决方案 > 在项目上使用自定义字体时数据绑定 MaterialTextView ClassCastException

问题描述

我在我的项目中使用数据绑定、MVVM 架构。

它以前工作得很好,但是当 Activity 尝试启动此布局时,应用程序突然崩溃。当我在项目的任何地方根本没有使用 MaterialTextView 时,它说com.google.android.material.textview.MaterialTextView 不能转换为com.github.ybq.android.spinkit.SpinKitView**。

我检查的东西

布局文件

<?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="네이버로 로그인&quot;
        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。这是非常奇怪的行为,我想知道为什么。

标签: android

解决方案


将功能更改为静态。

companion object {
    @JvmStatic
    @BindingAdapter("app:setFont")
    fun setTextStyle(view: TextView, type : String) {
        ...
    }
}

推荐阅读