更新: 如果我移动到另一个片段并返回到这个片段,TextView 会更新......
我无法通过使用 setValue() 或 postValue() 使 UI 中的 MutableLiveData 更新为新值。我可以通过将 MutableLiveData 更改为 ObservableData 来使其工作,但重点是使用 LiveData 而不是 ObservableData。
我在其他视图中也有类似的工作没有问题。不确定这里发生了什么......我唯一能想到的是我在相机活动(通过意图)和这个片段之间来回跳跃。在活动结果上,我将片段中的数据设置到 ViewModel。
我不相信我需要为片段中的值设置任何观察者,因为我在 XML 和 ViewModel 之间有 2 路数据绑定。
my_fragment.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="myViewModel"
type="com.example.myapplication.MyViewModel" />
</data>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@={myViewModel.photosCount}"
tools:text="1" />
<Button
android:id="@+id/btnTakePhoto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Take Picture"
android:onClick="@{myViewModel::navClicked}"/>
</LinearLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)
视图模型.java
private MutableLiveData<String> photosCount = new MutableLiveData<>();
private MutableLiveData<Boolean> takePhoto = new MutableLiveData<>();
public MyViewModel() {
photosCount.setValue("0"); // …Run Code Online (Sandbox Code Playgroud) 我正在使用 datastore-preferences:1.0.0-alpha01 并且当数据存储值更新时我似乎无法恢复事件。我一直试图在片段和父活动中观察它,结果相同。当我创建 DataStore 的实例并观察值流时,我在声明观察者后立即收到一个事件(注册观察者后似乎很常见)。这将表明流正在运行,并且观察者正在按预期接收事件。然后我在同一个观察者内部更新首选项的值,该观察者从不接收事件。
我使用这篇文章作为参考https://medium.com/scalereal/hello-datastore-bye-sharedpreferences-android-f46c610b81d5,它与我用来比较我的实现的 repo 一起使用。显然,这个是有效的。https://github.com/PatilShreyas/DataStoreExample
数据存储实用程序
class DataStoreUtils(context: Context) {
companion object {
private const val TAG = "DataStoreUtils"
}
private val dataStore = context.createDataStore(name = Constants.PrefName.APP_PREFS)
suspend fun setString(prefKey: String, value: String) {
Log.d(TAG, "Setting $prefKey to $value")
dataStore.edit { it[preferencesKey<String>(prefKey)] = value }
}
suspend fun getString(prefKey: String): String? {
return dataStore.data.map { it[preferencesKey<String>(prefKey)] ?: return@map null }.first()
}
val usernameFlow: Flow<String?> = dataStore.data
.catch {
if (it is IOException) {
it.printStackTrace() …Run Code Online (Sandbox Code Playgroud) android android-lifecycle kotlin-flow android-jetpack-datastore
我正在尝试使用数据绑定在我的视图模型中处理 imeOption actionDone。
还有一些其他帖子没有提供我正在寻找的解决方案。我想用 BindingAdapter 在 XML 中设置它来处理 actionDone 事件。在其他帖子的解决方案之后,我不断收到不同的数据绑定错误。
我真的希望我能找到一个概述所有数据绑定 XML 语法的文档,以及为什么工作会导致很多文档(包括官方 Android 文档)使用 lambdas not/passing params 的混合而不加解释。稍微改变它并在gradle构建中绑定错误。
xml
<EditText
android:id="@+id/passwordEdit"
android:layout_width="0dp"
android:layout_height="42dp"
android:ems="10"
android:text="@={mainViewModel.password}"
android:inputType="textPassword"
android:imeOptions="actionDone"
app:onEditorActionDone="@{(view) -> mainViewModel.onEditorActionDone(view)}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/passwordTitle" />
Run Code Online (Sandbox Code Playgroud)
视图模型
@BindingAdapter({"onEditorActionDone"})
public void onEditorActionDone(EditText view) {
AppLog.d(TAG, "-> onEditorActionDone()");
view.setOnEditorActionListener((v, actionId, event) -> {
if (actionId == EditorInfo.IME_ACTION_DONE) {
//do login
}
//do nothing
});
}
Run Code Online (Sandbox Code Playgroud)
我试过了
app:onEditorActionDone="@{mainViewModel::onEditorActionDone}"
app:onEditorActionDone="@{(view) -> mainViewModel.onEditorActionDone()}"
app:onEditorActionDone="@{mainViewModel.onEditorActionDone}"
这是我的第一个 Kotlin 项目之一,我正在关注 android 的 Codelabs 以快速了解 Kotlin。Android 开发对我来说并不陌生,但我在谷歌上搜索问题的解决方案我在 Kotlin 中找到了比 Java 多的教程和解决方案。是时候开始转向该语言了,因为 Android 已经转向“Kotlin 优先”。
我不熟悉 var/val 以及如何设置 onClick() 侦听器。在玩这个项目时,我尝试了很多东西,并决定重新使用 XML 中的 android:onClick,这样我就不必在 Activity 中创建全局变量。
它开始在我身上崩溃 java.lang.InstantiationException
我注释掉了 Activity 中的所有代码,并删除了 xml 中的 android:onClick。我仍然遇到同样的错误。重建和清理项目后,我试过Invalidate Cache / Restart也无济于事。
我确定我可以创建一个新项目并重新实现我离开的代码,但我不能在更大的项目中做到这一点。我不知道是什么导致了这个错误,以及为什么无论我尝试什么它都不会消失。
活动_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/roll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="2"
android:textSize="36sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<Button
android:id="@+id/btnRoll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="Roll"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/roll" />
<Button
android:id="@+id/btnCountUp"
android:layout_width="wrap_content" …Run Code Online (Sandbox Code Playgroud) 尝试在仪器测试中使用 FragmentScenario 时,我收到以下错误。我认为这个问题与构建类型有关,因为测试是在“staging”而不是“debug”构建配置下运行的。
\n任何帮助将不胜感激。
\n错误
\njava.lang.RuntimeException: Unable to resolve activity for: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example/androidx.fragment.app.testing.FragmentScenario$EmptyFragmentActivity (has extras) }\nat androidx.test.core.app.InstrumentationActivityInvoker.startActivity(InstrumentationActivityInvoker.java:387)\nat androidx.test.core.app.InstrumentationActivityInvoker.startActivity(InstrumentationActivityInvoker.java:416)\nat androidx.test.core.app.ActivityScenario.launchInternal(ActivityScenario.java:265)\nat androidx.test.core.app.ActivityScenario.launch(ActivityScenario.java:226)\nat androidx.fragment.app.testing.FragmentScenario.internalLaunch(FragmentScenario.java:299)\nat androidx.fragment.app.testing.FragmentScenario.launchInContainer(FragmentScenario.java:282)\nat com.example.view.fragments.MainFragmentTest.testNavigation(MainFragmentTest.kt:139)\nat java.lang.reflect.Method.invoke(Native Method)\nat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)\nat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)\nat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)\nat org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)\nat androidx.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:80)\nat androidx.test.internal.runner.junit4.statement.RunAfters.evaluate(RunAfters.java:61)\nat androidx.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:549)\nat org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)\nat org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)\nat org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)\nat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)\nat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)\nat org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)\nat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)\nat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)\nat org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)\nat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)\nat org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)\nat org.junit.runners.ParentRunner.run(ParentRunner.java:413)\nat androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:154)\nat org.junit.runners.Suite.runChild(Suite.java:128)\nat org.junit.runners.Suite.runChild(Suite.java:27)\nat org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)\nat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)\nat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)\nat org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)\nat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)\nat org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)\nat org.junit.runners.ParentRunner.run(ParentRunner.java:413)\nat org.junit.runner.JUnitCore.run(JUnitCore.java:137)\nat org.junit.runner.JUnitCore.run(JUnitCore.java:115)\nat androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)\nat androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:395)\nat android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2189)\nRun Code Online (Sandbox Code Playgroud)\n正在运行的测试是谷歌关于测试导航的文档的吐槽图片https://developer.android.com/guide/navigation/navigation-testing#kotlin
\n@Test\nfun testNavigation() {\n // Create a TestNavHostController\n val navController = TestNavHostController(ApplicationProvider.getApplicationContext())\n …Run Code Online (Sandbox Code Playgroud)