无法在 xml 中直接使用方法

Can't use method direct in xml

Android Studio 3.6

在build.gradle中:

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
    viewBinding {
        enabled = true
    }
    dataBinding {
        enabled = true
}

主要活动:

  import android.os.Bundle
    import androidx.appcompat.app.AppCompatActivity
    import com.myproject.android.androidtestproject.BuildConfig
    import com.myproject.android.androidtestproject.R
    import com.myproject.android.androidtestproject.databinding.MainActivityBinding

import com.myproject.android.androidtestproject.util.Debug
    class MainActivity : AppCompatActivity() {
        private lateinit var binding: MainActivityBinding
        private val TAG = MainActivity::class.java.name

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.main_activity)
            binding = MainActivityBinding.inflate(layoutInflater)
            val view = binding.root
            setContentView(view)
            init()
    }

我想在xml中直接使用DateUtil.getCurrrentDateAsString()

所以我在布局中使用了这个main_activity.xml

android:text='@{DateUtil.getCurrrentDateAsString()}'

此处布局:

<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="com.myproject.android.androidtestproject.util.DateUtil" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/appNameTextView"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/default_margin"
            android:gravity="center"
            android:textSize="18sp"
            app:layout_constraintBottom_toTopOf="@+id/loadListButton"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/currentDateTextView"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text='@{DateUtil.getCurrrentDateAsString()}'
            app:layout_constraintBottom_toTopOf="@+id/loadListButton"
            app:layout_constraintEnd_toEndOf="@+id/appNameTextView"
            app:layout_constraintStart_toStartOf="@+id/appNameTextView"
            app:layout_constraintTop_toBottomOf="@+id/appNameTextView" />

        <Button
            android:id="@+id/loadListButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/default_margin"
            android:layout_marginBottom="@dimen/default_margin"
            android:text="@string/load_list"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="@+id/appNameTextView"
            app:layout_constraintStart_toStartOf="parent" />


    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

这里 DateUtil.kt :

import java.text.SimpleDateFormat
import java.util.*

class DateUtil {
    companion object {
        const val DEFAULT_DATE_FORMAT = "dd.MM.yyyy"
        const val ISO_DATE_FORMAT = "yyyy-MM-dd"
        @JvmStatic
        fun getCurrrentDateAsString(pattern: String = DEFAULT_DATE_FORMAT): String {
            val currentDate = getCurrentDate()
            val currentDateAsString = getDateAsString(currentDate, pattern)
            return currentDateAsString
        }

        fun getCurrentDate(): Date {
            return Date()
        }

        // if pattern is null then will be use defaultDTCDateFormat
        fun getDateAsString(date: Date?, pattern: String = DEFAULT_DATE_FORMAT): String {
            if (date == null) {
                return ""
            }
            var sdf: SimpleDateFormat? = null
            return try {
                sdf = SimpleDateFormat(pattern)
                sdf.format(date)
            } catch (ex: IllegalArgumentException) {
                sdf = SimpleDateFormat(pattern)
                sdf.format(date)
            }
        }
    }
}

但是当我尝试构建时出现错误:

> Task :app:validateSigningDebug UP-TO-DATE

> Task :app:kaptDebugKotlin FAILED
AndroidTestProject/android/AndroidTestProject/app/build/generated/source/kapt/debug/com/myproject/android/androidtestproject/DataBinderMapperImpl.java:9: error: cannot find symbol
import com.gmail.alexei28.android.androidtestproject.databinding.MainActivityBindingImpl;
                                                                ^
  symbol:   class MainActivityBindingImpl
  location: package com.gmail.alexei28.android.androidtestproject.databinding
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:kaptDebugKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution
   > java.lang.reflect.InvocationTargetException (no error message)

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 10s

我想,你的问题出现是因为你调用的方法有参数("pattern"),你没有把它放在你的xml.

尽管它有默认值,但 DataBinding 无法解决这个问题。

也许有更优雅的决定,但你可以试试这些:

  1. 将您的 xml 代码更改为:

    android:text=@{DateUtil.getCurrrentDateAsString(DateUtil. DEFAULT_DATE_FORMAT)}'

  2. 添加一些 DataBinding adapter 以从代码中调用您的方法