尝试将数据绑定提供的上下文变量与BaseObservable一起使用时出错

Kas*_*rdi 9 android android-databinding

根据此评论Android数据绑定教程,我应该context在数据绑定时有一个变量:

根据需要,生成一个名为context的特殊变量,用于绑定表达式.上下文的值是来自根View的getContext()的Context.上下文变量将被具有该名称的显式变量声明覆盖.

我正在使用扩展类BaseObservable来设置我的数据,但无论我如何尝试context在我的@Bindable方法中引入变量,我都会遇到编译时错误:

java.lang.RuntimeException:失败,请参阅日志以获取详细信息.与方法关联的@Bindable必须遵循JavaBeans约定getStyledName(android.content.Context)

据我所知,我遵循JavaBeans惯例.我在BrUtil中跟踪了这一行的错误,但这也没有给我太多帮助.

我已经尝试更改我的方法和参数名称,我已经尝试添加<variable>for context<import>for for android.content.Context,但没有一个有任何区别.我的User.java下面有两个@Bindable方法,裸机getName()工作正常,但试图使用context变量的方法没有,所以我不认为这是我的数据绑定设置的其余部分的问题.

相关代码:

activity_main.xml:

<?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="user" type="com.kasra.androidsandbox.User" />
    </data>

    <LinearLayout
        android:id="@+id/main_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <android.support.v7.widget.Toolbar
            android:id="@+id/main_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            android:minHeight="?attr/actionBarSize"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

        <TextView
            android:id="@+id/main_textview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="@{user.getStyledName(context)}" />
    </LinearLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)

User.java:

public class User extends BaseObservable {
    private String name;

    public User(String name) {
        this.name = name;
    }

    @Bindable
    public String getName() {
        return this.name;
    }

    @Bindable
    public CharSequence getStyledName(Context ctx) {
        int color = ctx.getResources().getColor(R.color.branded_pink);

        Spannable textSpan = new SpannableString(name);
        textSpan.setSpan(new ForegroundColorSpan(color), 0, textSpan.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        return textSpan;
    }

}
Run Code Online (Sandbox Code Playgroud)

MainActivity.java:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    User user = new User("Kasra");
    binding.setUser(user);

    Toolbar toolbar = (Toolbar) findViewById(R.id.main_toolbar);
    setSupportActionBar(toolbar);
}
Run Code Online (Sandbox Code Playgroud)

Lis*_*ray 17

我不知道这是一个错误或预期的行为,但我自己观察到这种行为,所以你不是疯了.

解决方法是创建一个未@Bindable在用户中标记的方法- 需要上下文的方法.此方法不受JavaBeans命名约定的约束.

重要提示:为了确保更新它,应该将任何可能更改的@Bindable字段作为输入.

User.java

public class User extends BaseObservable {
    private String name;

    public User(String name) {
        this.name = name;
    }

    @Bindable
    public String getName() {
        return this.name;
    }

    public CharSequence getStyledName(Context ctx, String name) {
        // construct styled name here
    }
}
Run Code Online (Sandbox Code Playgroud)

在你的布局中:

<TextView
        android:id="@+id/main_textview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="@{user.getStyledName(context, user.name)}" />
Run Code Online (Sandbox Code Playgroud)