每当我将项目插入 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
我正在开发一个问答游戏,我想将一些 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) 无需ViewModel()仅使用简单的类进行扩展,我就可以实现 LiveData 和 DataBinding 示例,但我在 google 开发人员文档中显示了扩展ViewModel()以创建 LiveData 对象。那么为什么我们需要扩展它呢?
https://developer.android.com/topic/libraries/architecture/livedata
我得到了实时数据观察者和一个需要来自两个观察者的结果的函数。当两个观察者都收到数据时如何调用这个函数?不是代码看起来像这样
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) 我有一个项目列表,其中每个项目都有一个复选框。复选框的状态需要存储在 中,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
我有一个在片段上调用的 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) 我正在尝试弄清楚流/状态流和数据绑定。
\n在我的项目中,我有 Room 中的“打印机”列表,以及 SharedPreferences 中的“默认打印机”的 ID。
\n\n我是否使用了良好的流程并做得很好,还是出了什么问题?
\n房间给我一个Flow<List<Printer>>。借助我的适配器,我将其显示在回收器视图中viewModel.allPrinters.collect。
但是,当我想从房间绑定资源时,绑定“需要”LiveData 或 StateFlow,这是我的困难,因为 stateIn 需要协程。
\n我怎样才能从我的默认打印机Flow<List<Printer>>(通过他的属性“id”在列表中找到它)并确保列表/项目是否更新,我的参考也将获得更新?\n如果我更改打印机的名称defaultPrinter并将其更新到 room(感谢我的存储库/room DAO),我希望在我的对象defaultPrinter和列表中更改名称。
您还可以确认我的变量类型defaultPrinter应该是StateFlow<Printer?>
注意:当我更新项目时,printerRoomDAO.update(item:Printer)我必须传递数据对象的副本Printer(新引用),否则我的 UI 将不会更新。
isPrinterListEmpty这是我的 ViewModel 中的示例
val hasNoPrinter = allPrinters.mapLatest {\n it.isEmpty()\n}.asLiveData()\nRun Code Online (Sandbox Code Playgroud)\n它运行良好,但我不应该使用 StateFlow 吗?怎么做 ?因为stateIn()需要一个协程,而我下面的尝试不起作用。
val hasNoPrinter = …Run Code Online (Sandbox Code Playgroud) data-binding kotlin android-livedata kotlin-flow kotlin-stateflow
出于某种原因,我的单例存储库是从后台线程多次创建的,但是,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) 我正在尝试对应该显示通过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
让应用程序使用LiveData和ViewModel for UI来观察存储库中的数据更新。
一切正常。现在有人提出“ LiveData尚未被很好地采用,也许应该切换到使用协程的频道”。
首先,不确定有关LiveData的陈述是否正确。我敢肯定,协程的功能可以在没有LiveData的情况下完成。但是我觉得每个人都有自己的目标任务,而从Google的语音/示例中来看,LiveData是使用Android体系结构组件构建的,用于诸如在数据存储库和UI之间提供实时数据通道的情况。
该频道是kotlin的语言功能。当然可以在许多情况下使用它。我只是希望不是因为它已命名为“ channel”,所以人们觉得比这里使用LiveData更合适。
一个不太合适的示例是,消息总线/事件队列是否也适合在使用LiveData的地方使用?他们也可以订阅/观察。
只是没有足够的有力证据来证明LiveData在这种情况下更好用,或者协程通道更好,而不是非常了解该通道。
任何人都想分享一些想法吗?
android android-livedata android-architecture-components kotlin-coroutines
android-livedata ×10
android ×6
kotlin ×6
java ×2
android-architecture-components ×1
android-room ×1
data-binding ×1
firebase ×1
kotlin-flow ×1
lazycolumn ×1
mvvm ×1