标签: android-livedata

插入项目时 RecyclerView 行闪烁/闪烁

每当我将项目插入 Room 数据库时,我的回收器视图都会闪烁包含新插入的视图持有者的行(列表的其余部分不会闪烁)。我正在使用 LiveData 通过在观察到的 ViewModel 方法的 onChanged() 中调用submitList(list)来自动更新我的列表。我的适配器扩展了 ListAdapter,并且我正在使用 DiffUtil 来跟踪列表中的更改。话虽这么说,我不会直接调用 notificationItemInserted(position),因为 DiffUtil 应该为我执行此操作。有两种情况会插入一个项目 (1) 在列表末尾插入一个全新的项目 (2) 将已删除的项目重新插入到列表中。在这两种情况下,该项目都会自行插入然后闪烁。我读过很多帖子,人们建议在回收器视图上禁用动画,但这对我来说不是一个选择,因为我依赖于代码中其他地方的动画。任何其他建议将不胜感激。我试图保持发布的代码简短,但如果有帮助的话我可以发布更多内容。

MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

@Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    initComponents();
    initRecyclerView();
    setListeners();
    setListObserver();
    createItemTouchHelper();
  }

  private void setListObserver() {
    viewModel.getAllItems().observe(this, new Observer<List<ListItem>>() {
      @Override
      public void onChanged(List<ListItem> newList) {
        adapterMain.submitList(newList);
      }
    });
  }

...

// Inserts a new ListItem when MainActivity's EditText is used
  public void onClick(View v) {
    if (v.getId() == R.id.img_add_item_main) …
Run Code Online (Sandbox Code Playgroud)

java android-recyclerview android-room android-livedata android-diffutils

1
推荐指数
1
解决办法
2305
查看次数

无法填充 ArrayList 类型的 MutableLiveData,结果始终为 null

我正在开发一个问答游戏,我想将一些 id 存储在 MutableLiveData 数组列表中。因此,我创建了一个函数来循环数据库中的所有文档并将每个 ID 添加到数组列表中。但结果总是空的。我不明白我哪里错了?

我正在使用 MVVM 结构

游戏视图模型:

class GameViewModel : ViewModel() {

// database instance
val db = FirebaseFirestore.getInstance()

// the current category
private val _category = MutableLiveData<String>()
val category: LiveData<String>
    get() = _category

// the list of questionIds of the selected category
private val _questionIdsArray = MutableLiveData<ArrayList<Long>>()
val questionIdsArray: LiveData<ArrayList<Long>>
    get() = _questionIdsArray

// the current question
private val _question = MutableLiveData<String>()
val question: LiveData<String>
    get() = _question


/**
 * Set Current Category
 */
fun …
Run Code Online (Sandbox Code Playgroud)

kotlin firebase android-studio android-livedata

1
推荐指数
1
解决办法
684
查看次数

为什么我们需要为 DataBinding 和 LiveData 扩展“ViewModel()”来创建 LiveData 对象

无需ViewModel()仅使用简单的类进行扩展,我就可以实现 LiveData 和 DataBinding 示例,但我在 google 开发人员文档中显示了扩展ViewModel()以创建 LiveData 对象。那么为什么我们需要扩展它呢?

https://developer.android.com/topic/libraries/architecture/livedata

android kotlin android-livedata mutablelivedata

1
推荐指数
1
解决办法
848
查看次数

如何观察两个 LiveData 并一起使用结果。如何实现MediatorLiveData?

我得到了实时数据观察者和一个需要来自两个观察者的结果的函数。当两个观察者都收到数据时如何调用这个函数?不是代码看起来像这样

firstViewModel.dataOne.observe(viewLifecycleOwner) {
        secondViewModel.dataTwo.observe(viewLifecycleOwner) { dataTwoResult ->
            setAssociateInfo(dataTwoResult, it) // <--- send two parameters from to observers together
        }
    }
Run Code Online (Sandbox Code Playgroud)

android kotlin android-livedata

1
推荐指数
1
解决办法
3340
查看次数

当实时数据更改时,Android Compose 惰性列不会更新

我有一个项目列表,其中每个项目都有一个复选框。复选框的状态需要存储在 中,viewmodel并且最好中的列表viewmodel应该是唯一的事实来源。

@Composable
fun Screen(viewModel: ViewModel) {
    val list by viewModel.items.observeAsState()

    LazyColumn {
        list?.let { items ->
            items(items) { item -> 
                ListItem(
                    text = {
                        Text(item.name)
                    },
                    secondaryText = {
                        Text(item.phoneNumber)
                    },
                    icon = {
                        Checkbox(
                            modifier = Modifier.padding(8.dp),
                            checked = item.selected,
                            onCheckedChange = {
                                //TODO

                            }
                        )
                    }
                )
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试item.selected通过更新回调中的列表(MutableLiveData<List<Object>>in viewmodel)来更新onCheckedChange,但 UI 没有更新。如果我向下滚动然后向上滚动,用户界面会更新,并且该复选框似乎已被选中。为什么不更新?

android-livedata android-jetpack android-jetpack-compose lazycolumn

1
推荐指数
1
解决办法
7926
查看次数

为什么 livedata 观察会触发两次?

我有一个在片段上调用的 livedata 对象。第一次工作正常,它只触发一次,但第二次我输入片段时它触发两次,不明白为什么。

这就是我所说的观察:

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
    return inflater.inflate(R.layout.activity_train_with_famous_detail, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    setupUi(view)
    (activity as TrainingWithFamousActivity).hideToolbar()
    setupListCategoryVideos(view)
    viewModel.getVideosData()
    viewModel.videosData.observe(viewLifecycleOwner, Observer {
        //second time I enter the fragment it triggers his twice
        videoCategoryAdapter.loadItems(it)
    })
    viewModel.videoSelected?.let { loadTrainWithFamousDetailsData(it) }
}
Run Code Online (Sandbox Code Playgroud)

这是我的视图模型中的方法:

val videosData = MutableLiveData<List<DtoCelebrityResource>>()
fun getVideosData() {
    showLoader()

    trainingWithFamousUseCase
        .build(this)
        .executeWithError({
            videosData.value = it
            hideLoader()
        }, {
            hideLoader()
        })
}
Run Code Online (Sandbox Code Playgroud)

android mvvm kotlin android-livedata

1
推荐指数
1
解决办法
4020
查看次数

Android Flow/StateFlow 和数据绑定/Room

我正在尝试弄清楚流/状态流和数据绑定。

\n

在我的项目中,我有 Room 中的“打印机”列表,以及 SharedPreferences 中的“默认打印机”的 ID。

\n

这是我的架构:\n在此输入图像描述

\n

1\xc2\xb0/ 问题:我在这个架构中表现良好?

\n

我是否使用了良好的流程并做得很好,还是出了什么问题?

\n

2\xc2\xb0/ 第一个问题:在我的列表中获取我的默认打印机

\n

房间给我一个Flow<List<Printer>>。借助我的适配器,我将其显示在回收器视图中viewModel.allPrinters.collect

\n

但是,当我想从房间绑定资源时,绑定“需要”LiveData 或 StateFlow,这是我的困难,因为 stateIn 需要协程。

\n

我怎样才能从我的默认打印机Flow<List<Printer>>(通过他的属性“id”在列表中找到它)并确保列表/项目是否更新,我的参考也将获得更新?\n如果我更改打印机的名称defaultPrinter并将其更新到 room(感谢我的存储库/room DAO),我希望在我的对象defaultPrinter和列表中更改名称。

\n

您还可以确认我的变量类型defaultPrinter应该是StateFlow<Printer?>

\n

注意:当我更新项目时,printerRoomDAO.update(item:Printer)我必须传递数据对象的副本Printer(新引用),否则我的 UI 将不会更新。

\n

3\xc2\xb0/ 第二个问题:使用状态流看起来很复杂

\n

isPrinterListEmpty这是我的 ViewModel 中的示例

\n
val hasNoPrinter = allPrinters.mapLatest {\n    it.isEmpty()\n}.asLiveData()\n
Run Code Online (Sandbox Code Playgroud)\n

它运行良好,但我不应该使用 StateFlow 吗?怎么做 ?因为stateIn()需要一个协程,而我下面的尝试不起作用。

\n
val hasNoPrinter = …
Run Code Online (Sandbox Code Playgroud)

data-binding kotlin android-livedata kotlin-flow kotlin-stateflow

1
推荐指数
1
解决办法
2643
查看次数

为什么我的Singleton是同步的,但是它被多次创建?

出于某种原因,我的单例存储库是从后台线程多次创建的,但是,synchronized应该有帮助.有人可以帮忙吗?如果需要,我将提供代码片段和github链接.

我的IntentService类:

  @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Log.d(MainActivity.TAG, "ArticleIntentService - onHandleIntent");


        LiveData<List<Article>> liveArticles = ArticleRepository.getInstance(getApplication())
                .loadFromNetwork(PAGE_NUMBER, PAGE_SIZE);
        PAGE_NUMBER++;
        liveArticles.observeForever(articles -> {
            Log.d(MainActivity.TAG, "onStartJob - onChanged!!!!!!");
//                liveArticles.removeObserver(this);
            NotificationUtils.showNotification(context, articles.get(0).getSectionName(), articles.get(0).getWebTitle());

        });

    }
Run Code Online (Sandbox Code Playgroud)

我的存储库:

public static ArticleRepository INSTANCE;

public static synchronized ArticleRepository getInstance(Application application){
    if(INSTANCE == null){
        Log.d(TAG, "ArticleRepository getInstance is NULL");
        return  new ArticleRepository(application);
    }

    return INSTANCE;
}

private ArticleRepository(Application application) {
    Log.d(TAG, "ArticleRepository constructor");
    mContext = application;
    mArticles = new MutableLiveData<>();
    ArticleRoomDatabase db = ArticleRoomDatabase.getInstance(application);
    mArticleDao = …
Run Code Online (Sandbox Code Playgroud)

java android kotlin android-intentservice android-livedata

0
推荐指数
1
解决办法
61
查看次数

Android数据绑定和LiveData:无法绑定到LiveData属性中的值

我正在尝试对应该显示通过ViewModel中的LiveData属性公开的数据的视图进行数据绑定,但是我没有找到将LiveData中的对象绑定到视图的方法。从XML中,我只能访问LiveData实例的value属性,而不能访问其中的对象。我错过了什么吗?

我的ViewModel:

class TaskViewModel @Inject
internal constructor(private val taskInteractor: taskInteractor)
    : ViewModel(), TaskContract.ViewModel {

    override val selected = MutableLiveData<Task>()
    val task: LiveData<Task> = Transformations.switchMap(
        selected
    ) { item ->
        taskInteractor
            .getTaskLiveData(item.task.UID)
    }
    ... left out for breivety ... 
}
Run Code Online (Sandbox Code Playgroud)

我试图将任务对象的值绑定到我的视图中,但是当尝试在我的视图中设置任务的值时,我只能这样做android:text="@={viewmodel.task.value}"。我无权访问任务对象的字段。在LiveData对象中提取对象值的诀窍是什么?

我的任务课:

@Entity(tableName = "tasks")
data class Task(val id: String, 
                val title: String, 
                val description: String?, 
                created: Date, 
                updated: Date, 
                assigned: String?)
Run Code Online (Sandbox Code Playgroud)

android android-databinding android-livedata android-viewmodel

0
推荐指数
2
解决办法
1274
查看次数

android LiveData或协程通道

让应用程序使用LiveData和ViewModel for UI来观察存储库中的数据更新。

一切正常。现在有人提出“ LiveData尚未被很好地采用,也许应该切换到使用协程的频道”。

首先,不确定有关LiveData的陈述是否正确。我敢肯定,协程的功能可以在没有LiveData的情况下完成。但是我觉得每个人都有自己的目标任务,而从Google的语音/示例中来看,LiveData是使用Android体系结构组件构建的,用于诸如在数据存储库和UI之间提供实时数据通道的情况。

该频道是kotlin的语言功能。当然可以在许多情况下使用它。我只是希望不是因为它已命名为“ channel”,所以人们觉得比这里使用LiveData更合适。

一个不太合适的示例是,消息总线/事件队列是否也适合在使用LiveData的地方使用?他们也可以订阅/观察。

只是没有足够的有力证据来证明LiveData在这种情况下更好用,或者协程通道更好,而不是非常了解该通道。

任何人都想分享一些想法吗?

android android-livedata android-architecture-components kotlin-coroutines

0
推荐指数
1
解决办法
276
查看次数