首页 > 解决方案 > 错误:找不到属性 android:onProgressChanged。错误:链接文件资源失败

问题描述

我正在尝试处理SeekBar'onProgressChange事件。我android:onProgressChanged="onSeekBarChanged"在我的 Activity kotlin 文件中添加了 xml 布局文件和函数:

fun onSeekBarChanged(view: View) {
    Log.d(TAG, "on SeekBarChanged")
}

但编译器抛出以下错误:

Android资源链接失败/home/radek/AndroidStudioProjects/TestMediaStore/app/build/intermediates/incremental/mergeDebugResources/stripped.dir/layout/activity_songfile_list.xml:37:错误:找不到属性android:onProgressChanged。错误:链接文件资源失败。

我究竟做错了什么?

编辑: 这也适用于来自不同侦听器的其他事件属性,例如:

我的布局:

<?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>
        <variable name="viewModel" type="com.example.testmediastore.MyViewModel"/>
    </data>
<androidx.coordinatorlayout.widget.CoordinatorLayout    
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:context=".SongFileListActivity">

    <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/app_bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/AppTheme.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:popupTheme="@style/AppTheme.PopupOverlay"/>

    </com.google.android.material.appbar.AppBarLayout>

    <FrameLayout
            android:id="@+id/frameLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <include layout="@layout/songfile_list"/>
    </FrameLayout>

    <SeekBar
            android:layout_width="match_parent"
            android:layout_height="wrap_content" android:id="@+id/seekbar_playback"
            android:progress="@{viewModel.playerProgress}"
            android:max="@{viewModel.playerProgressMax}"
            android:onProgressChanged="onSeekBarChanged"
            app:layout_behavior="@string/bottom_sheet_behavior"/>

    <fragment
            android:layout_width="wrap_content"
            android:layout_height="@dimen/play_control_height"
            android:name="com.example.testmediastore.PlayControlFragment"
            android:id="@+id/fragment"
            android:layout_gravity="bottom|center"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

标签: androidandroid-layoutandroid-databinding

解决方案


这是完全错误的:android:onProgressChanged="onSeekBarChanged"

正确的做法是:

android:onProgressChanged="@{viewModel::onSeekBarChanged}"

fun onSeekBarChanged(SeekBar seekBar, int progress, boolean fromUser) {
    Log.d(TAG, "on SeekBarChanged")
}

或者

android:onProgressChanged="@{() -> viewModel.onSeekBarChanged()}"

fun onSeekBarChanged() {
    Log.d(TAG, "on SeekBarChanged")
}

第一个解决方案称为方法引用文档)。该方法的签名应该与相应的监听器方法的签名相同。就我而言,它onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)来自SeekBar.OnSeekBarChangeListener

第二种方法称为侦听器绑定。你可以省略方法的参数。但要注意返回值:

如果您正在侦听的事件返回一个类型不是 void 的值,那么您的表达式也必须返回相同类型的值。例如,如果你想监听长点击事件,你的表达式应该返回一个布尔值。

onProgressChanged的返回值为void(Kotlin Unit),因此上述内容不适用。


推荐阅读