【问题标题】:Is it possible to set text of TextView with a method of ViewModel that returns String?是否可以使用返回字符串的 ViewModel 方法设置 TextView 的文本?
【发布时间】:2018-06-21 10:46:33
【问题描述】:

是否可以通过返回String的方法更改TextView的文本?

出于培训目的,我创建了这个ViewModel 类,它将User 对象放入List<User> mUserList,我想知道我是否可以使用ViewMode 方法将此用户的名字设置为TextView 的文本。我收到绑定错误,是否可以使用不使用 @BindingAdapter 注释而返回 String 的方法来解决此问题?

编辑:当我设置android:text="@{viewmodel.userList.toString()}" 时,它不会返回绑定错误,但会返回用户对象的字符串表示形式。但是当我使用android:text="@{viewmodel.getUserFirstNames()}" 时,我得到一个绑定错误。为什么会这样?

public class UsersViewModel extends ViewModel {

    private List<User> mUserList;

    public List<User> getUserList() {
        if (mUserList == null) {
            mUserList = loadUsers();
        }
        return mUserList;
    }

    /**
     * Dummy Method to fake web service
     *
     * @return list of users
     */
    private List<User> loadUsers() {
    // do something to load users
    List<User> userList = new ArrayList<>();
    User user = new User();
    user.setFirstName("John");
    user.setLastName("Adams");
    userList.add(user);

    user = new User();
    user.setFirstName("Lucy");
    user.setLastName("Adams");
    userList.add(user);

    return userList;

    }


    @NonNull
    private String getUserFirstNames() {
        if (mUserList != null && mUserList.size() > 0) {
            StringBuilder sb = new StringBuilder();
            sb.append("First Names:\n");
            for (User user : mUserList) {
                sb.append(user.getFirstName() + "\n");
            }

            return sb.toString();
        }

        return "empty";
    }
}

在 MainActivity 我假装加载数据 公共类 MainActivity 扩展 AppCompatActivity {

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

        ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        UsersViewModel usersViewModel =
                ViewModelProviders.of(this).get(UsersViewModel.class);
        usersViewModel.getUserList();
        activityMainBinding.setViewmodel(usersViewModel);
    }
}

在布局中我想知道是否可以使用 ViewModel 类设置 TextView 的文本

    <data>

        <variable
            name="viewmodel"
            type="com.example.tutorial1basics.viewmodel.UsersViewModel" />
    </data>

    <android.support.constraint.ConstraintLayout 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"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <TextView
            android:id="@+id/tv_users"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{viewmodel.getUserFirstNames()}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />



    </android.support.constraint.ConstraintLayout>
</layout>

【问题讨论】:

  • 我刚刚开始学习 MVVM,我想知道是否可以使用方法,而不是静态 @BindingAdapter、LiveData 或 ObservableField。这只是为了教育目的,我只是想知道这是否可能?
  • 你可以通过这个链接使用 MVP [this] (medium.com/@cervonefrancesco/…)
  • 是的,有可能。
  • 谢谢。我想这是不可能的。当我设置android:text="@{viewmodel.userList.toString()}" 时,它不会返回绑定错误,但会返回用户对象的字符串表示形式。但是当我使用android:text="@{viewmodel.getUserFirstNames()}" 时出现绑定错误。

标签: android android-databinding android-mvvm


【解决方案1】:

您想使用 BaseObservable 扩展您的模型。

点赞:

public class Post extends BaseObservable{
    @SerializedName("userId")
    @Expose
    private Integer userId;
    @SerializedName("id")
    @Expose
    private Integer id;
    @SerializedName("title")
    @Expose
    private String title;
    @SerializedName("body")
    @Expose
    private String body;

    @Bindable
    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
        notifyPropertyChanged(BR.userId);
    }

    @Bindable
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
        notifyPropertyChanged(BR.id);
    }

    @Bindable
    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
        notifyPropertyChanged(BR.title);
    }

    @Bindable
    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
        notifyPropertyChanged(BR.body);
    }
}

【讨论】:

  • 我实际上想知道扩展android.arch.lifecycle.ViewModel 的类是否可行。但据我了解,数据应该是某种 observable 以便能够使用方法或字段设置文本,对吧?如果我扩展 android.arch.lifecycle.ViewModel 类,那么我应该使用 Observable 和 getter 方法,对吗?
  • 我的错误是将getUserFirstNames() 方法设置为私有。我将它设置为公开,它现在可以工作了。您可以使用返回 String 的方法设置 TextView 的文本。扩展 android.arch.lifecycle.ViewModel 类的目的是为了让数据在设备旋转中存活,因为 ViewModel 类有它自己的生命周期。但是,如果没有 LiveData 或 ObservableField,您将无法通知用户的更改。
  • 是的,这完全取决于您的操作,您需要什么样的工作。
  • @Thracian 也许你可以在这篇文章中帮助我:stackoverflow.com/questions/57285153/…
猜你喜欢
  • 2017-03-07
  • 2016-10-14
  • 2020-02-27
  • 1970-01-01
  • 1970-01-01
  • 2016-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多