Как правильно передать данные из viewModel в функцию onClick с помощью привязки данных? - PullRequest
1 голос
/ 21 октября 2019

Я пытаюсь передать объект LiveData в качестве некоторого параметра функции привязки данных, и я постоянно получаю нулевое значение. Я пытался получить это значение, используя метод viewmodel.getTrainingActivity.observe()... внутри моего фрагмента, и это сработало, поэтому его необходимо связать с жизненным циклом живых данных, но я не могу решить эту проблему.
Как правильно передать упомянутые мной данные? ?

Мой метод onClick:

android:onClick="@{() -> presenter.showSelectActivityDialog(viewmodel.trainingActivity)}"

Мой метод докладчика:

public void showSelectActivityDialog(TrainingActivity trainingActivity){
    Log.i(TAG, "Training activity: " + trainingActivity.getName());
}

Мой класс viemodel:

public class TrainingFragmentViewModel extends ViewModel {
    public final static String TAG = TrainingFragmentViewModel.class.getSimpleName();
    private MediatorLiveData<TrainingStatus> status = new MediatorLiveData<>();
    private MediatorLiveData<String> time = new MediatorLiveData<>();
    private MediatorLiveData<String> distance = new MediatorLiveData<>();
    private MediatorLiveData<String> speed = new MediatorLiveData<>();
    private MediatorLiveData<String> calories = new MediatorLiveData();
    private MediatorLiveData<String> objective = new MediatorLiveData();
    private TrainingFragmentRepository trainingFragmentRepository;

    public TrainingFragmentViewModel(TrainingFragmentRepository repository) {
        Log.i(TAG, "VIEW MODEL CREATED");
        this.trainingFragmentRepository = repository;
        status.addSource(repository.getStatus(), status::setValue);
        time.addSource(repository.getTime(), time::setValue);
        distance.addSource(repository.getDistance(), distance::setValue);
        speed.addSource(repository.getDistance(), speed::setValue);
        calories.addSource(repository.getCalories(), calories::setValue);
        objective.addSource(repository.getObjective(), calories::setValue);
    }

    public LiveData<TrainingStatus> getStatus() {
        return status;
    }

    public MediatorLiveData<String> getTime() {
        return time;
    }

    public MediatorLiveData<String> getDistance() {
        return distance;
    }

    public MediatorLiveData<String> getSpeed() {
        return speed;
    }

    public MediatorLiveData<String> getCalories() {
        return calories;
    }

    public MediatorLiveData getObjective() {
        return objective;
    }

    public LiveData<List<TrainingActivity>> getTrainingActivities() {
        return trainingFragmentRepository.getAllTrainingActivities();
    }

    public LiveData<TrainingActivity> getTrainingActivity() {
        return trainingFragmentRepository.getTrainingActivity();
    }

    public static class Factory extends ViewModelProvider.NewInstanceFactory {
        private final TrainingFragmentRepository repository;

        public Factory(TrainingFragmentRepository repository) {
            this.repository = repository;

        }

        @SuppressWarnings("unchecked")
        @NonNull
        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
            return (T) new TrainingFragmentViewModel(repository);
        }

    }

}


ПолныйXML-файл:

<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"
    xmlns:bind="http://schemas.android.com/apk/res-auto">

    <data>

        <import type="android.view.View" />
        <import type=".features.training.TrainingStatus" />
        <variable
            name="viewmodel"
            type=".fragments.training.main_training.TrainingFragmentViewModel" />

        <variable
            name="presenter"
            type=".fragments.training.main_training.TrainingFragmentPresenter" />

    </data>


    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".fragments.training.main_training.TrainingFragment">

        <fragment
            android:id="@+id/fragmentTrainingWithMap"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintBottom_toTopOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            android:name=".fragments.training.trainingMap.googleMap.TrainingGoogleMapFragment"/>

        <include
            android:id="@+id/include3"
            layout="@layout/fragment_training_top_bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingRight="10dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <androidx.coordinatorlayout.widget.CoordinatorLayout
            android:id="@+id/main_training_layout"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/include3">


            <com.google.android.material.appbar.AppBarLayout
                android:id="@+id/appBarLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:elevation="0dp"
                app:layout_behavior=".fragments.training.main_training.BlockableAppBarLayoutBehaviour">


                <com.google.android.material.appbar.CollapsingToolbarLayout
                    android:id="@+id/training_collapsing_toolbar_layout"
                    android:layout_width="match_parent"
                    android:layout_height="370dp"
                    android:paddingLeft="10dp"
                    android:paddingRight="10dp"
                    app:layout_scrollFlags="exitUntilCollapsed|scroll|snap">


                    <FrameLayout
                        android:id="@+id/fragment_training_distance_and_activity_bar"
                        android:layout_width="match_parent"
                        android:layout_height="70dp"
                        android:layout_gravity="top"
                        android:layout_marginTop="220dp">

                        <LinearLayout
                            android:id="@+id/fragment_training_layout_distance"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="left"
                            android:orientation="vertical"
                            app:layout_collapseMode="none">

                            <TextView
                                android:id="@+id/textView28"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:text="DYSTANS km"
                                android:textAppearance="@style/TextAppearance.MyTheme.Subtitle1" />

                            <TextView
                                android:id="@+id/fragment_training_distance_textview"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:fontFamily="@font/stoltz_book"
                                android:text='@{viewmodel.distance ?? "00,00", default = "00,00"}'
                                android:textAppearance="@style/TextAppearance.MyTheme.Headline4"
                                android:textColor="@color/colorPrimary" />
                        </LinearLayout>

                        <ImageButton
                            android:id="@+id/imageButton7"
                            android:layout_width="60dp"
                            android:layout_height="60dp"
                            android:layout_gravity="bottom|right"
                            android:background="#00FFFFFF"
                            bind:srcCompat="@drawable/ic_bieg_w_kole"
                            android:onClick="@{() -> presenter.showSelectActivityDialog(viewmodel.trainingActivity)}"/>

                    </FrameLayout>
<!--                    android:onClick="@{() -> presenter.showSelectActivityDialog(viewmodel.trainingActivity)}"-->
                    <FrameLayout
                        android:id="@+id/fragment_training_add_stage_layout"
                        android:layout_width="60dp"
                        android:layout_height="60dp"
                        android:layout_gravity="top|left"
                        android:layout_marginLeft="20dp"
                        android:layout_marginTop="115dp"
                        android:layout_marginBottom="60dp"
                        android:visibility="@{viewmodel.status == TrainingStatus.PAUSED ? View.VISIBLE : View.GONE}">

                        <ImageButton
                            android:id="@+id/fragment_training_add_stage_imagebutton"
                            android:layout_width="match_parent"
                            android:layout_height="match_parent"
                            android:background="#00FFFFFF"
                            android:scaleType="fitXY"
                            android:src="@drawable/ic_dodaj_etap"
                            app:layout_collapseMode="none" />
                    </FrameLayout>


                    <FrameLayout
                        android:id="@+id/fragment_training_stop_layout"
                        android:layout_width="60dp"
                        android:layout_height="60dp"
                        android:layout_gravity="right|top"
                        android:layout_marginTop="115dp"
                        android:layout_marginRight="20dp"
                        android:layout_marginBottom="60dp"
                        android:visibility="@{viewmodel.status == TrainingStatus.PAUSED ? View.VISIBLE : View.GONE}">

                        <ImageButton
                            android:id="@+id/fragment_training_stop_trainig_imagebutton"
                            android:layout_width="match_parent"
                            android:layout_height="match_parent"
                            android:background="#00FFFFFF"
                            android:onClick="@{() -> presenter.onStopButtonClick()}"
                            android:scaleType="fitXY"
                            android:src="@drawable/ic_zakoncz_btn"
                            app:layout_collapseMode="none" />

                    </FrameLayout>


                    <LinearLayout
                        android:id="@+id/fragment_training_layout_tempo"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="right|top"
                        android:layout_marginTop="10dp"
                        android:layout_marginBottom="20dp"
                        android:gravity="right"
                        android:orientation="vertical"
                        app:layout_collapseMode="pin">

                        <TextView
                            android:id="@+id/textView23"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:text="TEMPO min./km"
                            android:textAppearance="@style/TextAppearance.MyTheme.Subtitle1" />

                        <TextView
                            android:id="@+id/fragment_training_tempo_textview"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:gravity="right"
                            android:text='@{viewmodel.speed ?? "00:00", default = "00:00"}'
                            android:textAppearance="@style/TextAppearance.MyTheme.Headline6" />
                    </LinearLayout>

                    <LinearLayout
                        android:id="@+id/fragment_trainig_start_trainig_layout"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center_horizontal|top"
                        android:layout_marginTop="70dp"
                        android:layout_marginBottom="60dp"
                        android:gravity="center"
                        android:orientation="vertical"
                        app:layout_collapseMode="parallax">


                        <FrameLayout
                            android:layout_width="140dp"
                            android:layout_height="140dp">

                            <include
                                layout="@layout/start_stop_button_layout"
                                android:layout_width="match_parent"
                                android:layout_height="match_parent"
                                bind:presenter="@{presenter}"
                                bind:viewmodel="@{viewmodel}" />

                        </FrameLayout>

                        <LinearLayout
                            android:layout_width="wrap_content"
                            android:layout_height="match_parent"
                            android:orientation="horizontal"
                            android:visibility="visible">

                            <TextView
                                android:id="@+id/textView26"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_marginRight="4dp"
                                android:gravity="center"
                                android:text="CEL:"
                                android:textAppearance="@style/TextAppearance.MyTheme.Subtitle1" />

                            <TextView
                                android:id="@+id/textView27"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_marginRight="4dp"
                                android:layout_weight="1"
                                android:text='@{viewmodel.objective == null ? "0" : viewmodel.objective, default = "0"}'
                                android:textAppearance="@style/TextAppearance.MyTheme.Body2" />

                            <TextView
                                android:id="@+id/textView30"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_weight="1"
                                android:text="km"
                                android:textAppearance="@style/TextAppearance.MyTheme.Caption" />
                        </LinearLayout>

                    </LinearLayout>

                    <LinearLayout
                        android:id="@+id/fragment_training_layout_time"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="top|left"
                        android:layout_marginTop="10dp"
                        android:layout_marginBottom="20dp"
                        android:orientation="vertical"
                        app:layout_collapseMode="pin">

                        <TextView
                            android:id="@+id/timerLabel2"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:text="CZAS TRWANIA"
                            android:textAppearance="@style/TextAppearance.MyTheme.Subtitle1" />

                        <TextView
                            android:id="@+id/fragment_training_timer_value_text_view"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:text='@{viewmodel.time ?? "00:00:00", default = "00:00:00"}'
                            android:textAppearance="@style/TextAppearance.MyTheme.Headline6" />

                    </LinearLayout>

                    <include
                        android:id="@+id/fragment_training_layout_bottom_bar"
                        layout="@layout/fragment_training_bottom_bar"
                        android:layout_width="match_parent"
                        android:layout_height="70dp"
                        android:layout_gravity="bottom"
                        bind:presenter="@{presenter}"
                        bind:viewmodel="@{viewmodel}" />

                    <include
                        android:id="@+id/fragment_training_layout_bottom_bar2"
                        layout="@layout/fragment_training_bottom_bar_2"
                        android:layout_width="wrap_content"
                        android:layout_height="70dp"
                        android:layout_gravity="bottom"
                        android:visibility="invisible"
                        bind:viewmodel="@{viewmodel}" />

                    <com.google.android.material.appbar.MaterialToolbar
                        android:id="@+id/profile_toolbar"
                        android:layout_width="match_parent"
                        android:layout_height="70dp"></com.google.android.material.appbar.MaterialToolbar>

                    <View
                        android:id="@+id/view5"
                        android:layout_width="match_parent"
                        android:layout_height="1dp"
                        android:layout_marginTop="300dp"
                        android:background="@color/greyedTextColor"
                        bind:layout_constraintEnd_toEndOf="parent"
                        bind:layout_constraintStart_toStartOf="parent"
                        bind:layout_constraintTop_toBottomOf="@+id/imageView8" />

                    <include
                        android:id="@+id/fragment_training_details_bar"
                        layout="@layout/fragment_training_details_bar"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="300dp"
                        android:visibility="gone" />


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

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

            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/fragment_training_map_bar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                android:paddingLeft="10dp"
                android:paddingTop="8dp"
                android:paddingRight="10dp"
                android:paddingBottom="8dp"
                bind:layout_anchor="@id/appBarLayout"
                bind:layout_anchorGravity="bottom">


                <ImageButton
                    android:id="@+id/imageButton3"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:background="#00FFFFFF"
                    android:scaleType="fitXY"
                    bind:layout_constraintBottom_toBottomOf="parent"
                    bind:layout_constraintEnd_toEndOf="parent"
                    bind:layout_constraintTop_toTopOf="parent"
                    bind:srcCompat="@drawable/ic_map_wysrodkuj" />

                <ImageButton
                    android:id="@+id/imageButton5"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:layout_marginEnd="8dp"
                    android:background="@drawable/map_satellite"
                    android:scaleType="fitXY"
                    bind:layout_constraintBottom_toBottomOf="parent"
                    bind:layout_constraintEnd_toStartOf="@+id/imageButton3"
                    bind:layout_constraintTop_toTopOf="parent" />

                <ImageButton
                    android:id="@+id/imageButton6"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:background="#00FFFFFF"
                    android:scaleType="fitXY"
                    android:src="@drawable/ic_map_aparat_btn"
                    app:layout_constraintStart_toStartOf="parent"
                    bind:layout_constraintBottom_toBottomOf="parent"
                    bind:layout_constraintTop_toTopOf="parent" />
            </androidx.constraintlayout.widget.ConstraintLayout>

        </androidx.coordinatorlayout.widget.CoordinatorLayout>

        <FrameLayout
            android:id="@+id/start_stop_on_map_layout"
            android:layout_width="110dp"
            android:layout_height="110dp"
            android:layout_marginBottom="32dp"
            android:visibility="gone"
            app:layout_constraintBottom_toBottomOf="@+id/fragmentTrainingWithMap"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent">

            <FrameLayout
                android:id="@+id/start_stop_on_map_layout_to_animate"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <include
                    layout="@layout/start_stop_button_layout"
                    android:layout_width="110dp"
                    android:layout_height="110dp"
                    android:background="#00FFFFFF"
                    bind:presenter="@{presenter}"
                    bind:viewmodel="@{viewmodel}" />
            </FrameLayout>

        </FrameLayout>



    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

1 Ответ

0 голосов
/ 21 октября 2019

почему вы разделили презентатора и просмотр модели? По концепции MVVM ведущим должен быть ViewModel.

Так что showSelectActivityDialog должен быть частью ViewModel и должен получать прямое значение getTrainingActivity().getValue()

Также имейте в виду, что обгон с MVVM не очень хорошая вещь, рассмотрите возможность управления потоком пользовательского интерфейсас новым компонентом навигационной арки или по-старому только внутри Activity / Fragment

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...