Можно ли установить текст TextView с помощью метода ViewModel, который возвращает String?

Можно ли изменить текст TextView с помощью метода, возвращающего String?

В целях обучения я создал этот класс ViewModel, он помещает объект User в List<User> mUserList, и мне интересно, могу ли я установить имена этих пользователей в виде текста TextView с помощью метода ViewMode. Я получаю ошибку привязки, можно ли это исправить с помощью метода, который возвращает String без использования аннотации @BindingAdapter?

Изменить: когда я устанавливаю 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 extends 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);
    }
}

В макете мне интересно, можно ли установить текст TextView с классом ViewModel

    <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>

person Thracian    schedule 21.06.2018    source источник
comment
Вы хотите использовать для этого ObservableField ‹String› developer.android.com/reference/android/ привязка данных /   -  person Mayur Patel    schedule 21.06.2018
comment
Я только начал изучать MVVM, и мне было интересно, возможно ли это с помощью метода, а не с помощью статических @BindingAdapter, LiveData или ObservableField ‹String›. Это просто в образовательных целях, мне просто интересно, возможно это или нет?   -  person Thracian    schedule 21.06.2018
comment
вы можете использовать MVP по этой ссылке [this] (medium.com/ @ cervonefrancesco /)   -  person amin mahmoudi    schedule 21.06.2018
comment
Да, это возможно.   -  person Mayur Patel    schedule 21.06.2018
comment
Спасибо. Думаю, это невозможно. Когда я устанавливаю android:text="@{viewmodel.userList.toString()}", он не возвращает ошибку привязки, но возвращает строковое представление объектов User. Но когда я использую android:text="@{viewmodel.getUserFirstNames()}", я получаю ошибку привязки.   -  person Thracian    schedule 21.06.2018
comment
Вы можете расширить свою модель с помощью BaseObservable.   -  person Mayur Patel    schedule 21.06.2018
comment
@MayurPatel, не могли бы вы предоставить для него сниппер?   -  person Thracian    schedule 21.06.2018
comment
@Thracian Да, конечно.   -  person Mayur Patel    schedule 21.06.2018
comment
@Thracian Вы можете получить больше в этом блоге medium.com/@fabioCollini/android-data -binding-f9f9d3afc761   -  person Mayur Patel    schedule 21.06.2018


Ответы (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);
    }
}
person Mayur Patel    schedule 21.06.2018
comment
Мне действительно было интересно, возможно ли это с классом, расширяющим android.arch.lifecycle.ViewModel. Но насколько я понимаю, данные должны быть своего рода наблюдаемыми, чтобы можно было установить текст с помощью метода или поля, верно? Если я расширяю класс android.arch.lifecycle.ViewModel, тогда я должен использовать Observable ‹String› и метод получения, верно? - person Thracian; 21.06.2018
comment
Моя ошибка заключалась в том, чтобы установить метод getUserFirstNames() как закрытый. Я выставил его на всеобщее обозрение, и теперь он работает. Вы можете установить текст TextView с помощью метода, который возвращает String. Целью расширения класса android.arch.lifecycle.ViewModel является сохранение данных при ротации устройства, поскольку класс ViewModel имеет собственный жизненный цикл. Однако вы не можете уведомлять об изменениях пользователя без LiveData или ObservableField. - person Thracian; 21.06.2018
comment
Да, это полностью зависит от того, какая работа вам нужна. - person Mayur Patel; 21.06.2018
comment
@Thracian, возможно, вы поможете мне в этом сообщении: stackoverflow.com/questions/57285153/ - person Matan Marciano; 31.07.2019