- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试将 LiveData 对象作为一些数据绑定(bind)函数参数传递,但我不断得到 null 值。我尝试在我的 fragment 中使用 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>
最佳答案
为什么要分离 Presenter 和 View Model?按MVVM 概念presenter 应该是ViewModel。
所以 showSelectActivityDialog
应该是 ViewModel 的一部分,并且应该直接获取值 getTrainingActivity().getValue()
此外,请记住,使用 MVVM 超车并不是一件好事,请考虑使用新的 Navigation arch 组件或仅在 Activity/Fragment 中以旧方式管理 UI 流
关于android - 使用数据绑定(bind)将数据从 viewModel 传递到 onClick 函数的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58482190/
Github:https://github.com/jjvang/PassIntentDemo 我一直在关注有关按 Intent 传递对象的教程:https://www.javacodegeeks.c
我有一个 View ,其中包含自动生成的 text 类型的 input 框。当我单击“通过电子邮件发送结果”按钮时,代码会将您带到 CalculatedResults Controller 中的 Em
我有一个基本的docker镜像,我将以此为基础构建自己的镜像。我没有基础镜像的Dockerfile。 基本上,基本镜像使用两个--env arg,一个接受其许可证,一个选择在容器中激活哪个框架。我可以
假设我想计算 2^n 的总和,n 范围从 0 到 100。我可以编写以下内容: seq { 0 .. 100 } |> Seq.sumBy ((**) 2I) 但是,这与 (*) 或其他运算符/函数不
我有这个网址: http://www.example.com/get_url.php?ID=100&Link=http://www.test.com/page.php?l=1&m=7 当我打印 $_G
我想将 window.URL.createObjectURL(file) 创建的地址传递给 dancer.js 但我得到 GET blob:http%3A//localhost/b847c5cd-aa
我想知道如何将 typedef 传递给函数。例如: typedef int box[3][3]; box empty, *board[3][3]; 我如何将 board 传递给函数?我
我正在将一些代码从我的 Controller 移动到核心数据应用程序中的模型。 我编写了一个方法,该方法为我定期发出的特定获取请求返回 NSManagedObjectID。 + (NSManagedO
为什么我不能将类型化数组传递到采用 any[] 的函数/构造函数中? typedArray = new MyType[ ... ]; items = new ko.observableArray(ty
我是一名新的 Web 开发人员,正在学习 html5 和 javascript。 我有一个带有“选项卡”的网页,可以使网页的某些部分消失并重新出现。 链接如下: HOME 和 JavaScript 函
我试图将对函数的引用作为参数传递 很难解释 我会写一些伪代码示例 (calling function) function(hello()); function(pass) { if this =
我在尝试调用我正在创建的 C# 项目中的函数时遇到以下错误: System.Runtime.InteropServices.COMException: Operation is not allowed
使用 ksh。尝试重用当前脚本而不修改它,基本上可以归结为如下内容: `expr 5 $1 $2` 如何将乘法命令 (*) 作为参数 $1 传递? 我首先尝试使用“*”,甚至是\*,但没有用。我尝试
我一直在研究“Play for Java”这本书,这本书非常棒。我对 Java 还是很陌生,但我一直在关注这些示例,我有点卡在第 3 章上了。可以在此处找到代码:Play for Java on Gi
我知道 Javascript 中的对象是通过引用复制/传递的。但是函数呢? 当我跳到一些令人困惑的地方时,我正在尝试这段代码。这是代码片段: x = function() { console.log(
我希望能够像这样传递参数: fn(a>=b) or fn(a!=b) 我在 DjangoORM 和 SQLAlchemy 中看到了这种行为,但我不知道如何实现它。 最佳答案 ORM 使用 specia
在我的 Angular 项目中,我最近将 rxjs 升级到版本 6。现在,来自 npm 的模块(在 node_modules 文件夹内)由于一些破坏性更改而失败(旧的进口不再有效)。我为我的代码调整了
这个问题在这里已经有了答案: The issue of * in Command line argument (6 个答案) 关闭 3 年前。 我正在编写一个关于反向波兰表示法的 C 程序,它通过命
$(document).ready(function() { function GetDeals() { alert($(this).attr("id")); } $('.filter
下面是一个例子: 复制代码 代码如下: use strict; #这里是两个数组 my @i =('1','2','3'); my @j =('a','b','c'); &n
我是一名优秀的程序员,十分优秀!