我们决定将RxJava的Flowable与房间持久化库结合使用。我们有一些表,其中的内容由服务以不确定的间隔添加(每隔几秒钟有2-3次更新插入),并且在BaseAdapter中订阅该表的行,以便在视图中进行实时更改。
问题是,每当有任何更新/插入操作时,我们都会再次获得整个列表,从而使基适配器重新生成视图。也可以进行删除操作,使行的长度对我们没有用处。
我想问一下,是否有其他运营商支持实时数据,并在新数据上调用onNext,并提供删除操作的完整列表。
发布于 2018-06-29 18:11:44
在BaseAdapter中订阅
使用带有细粒度notify*调用的RecyclerView,如notifyItemInserted,而不是ListView
问题是,当有任何update/insert操作时,我们再次得到整个列表
对于LiveData<List<T>>和Flowable<List<T>>来说,这都是完全预期的行为。
使基适配器重新生成视图。
这是因为你没有使用DiffUtil,或者你没有使用RecyclerView的新功能,ListAdapter (它在内部自动处理差异化)
提供了有关删除操作完整列表。
它实际上已经提供了整个列表(当然,没有删除的项目)。
AAC端的解决方案是使用DataSource.Factory<Integer, T>而不是Flowable<List<T>>/LiveData<List<T>>,这样您就可以通过LivePagedListBuilder创建LiveData<PagedList<T>>,您可以将该LivePagedListBuilder设置为您的PagedListAdapter。这样,它只获取给定的页面大小,而不是整个列表,并处理差异。
编辑:
@Entity(tableName = Task.TABLE_NAME)
public class Task {
public static DiffUtil.ItemCallback<Task> DIFF_CALLBACK = new DiffUtil.ItemCallback<Task>() {
@Override
public boolean areItemsTheSame(@NonNull Task oldItem, @NonNull Task newItem) {
return oldItem.id == newItem.id;
}
@Override
public boolean areContentsTheSame(@NonNull Task oldItem, @NonNull Task newItem) {
return oldItem.equals(newItem);
}
};
public static final String TABLE_NAME = "TASK";
public static final String COLUMN_ID = "task_id";
public static final String COLUMN_TEXT = "task_text";
public static final String COLUMN_DATE = "task_date";和
@Dao
public interface TaskDao {
@Query("SELECT * FROM " + Task.TABLE_NAME + " ORDER BY " + Task.COLUMN_DATE + " ASC ")
DataSource.Factory<Integer, Task> tasksSortedByDate();
// ...
}和
public class TaskViewModel
extends ViewModel {
private final TaskDao taskDao;
private LiveData<PagedList<Task>> liveResults;
public TaskViewModel(TaskDao taskDao) {
this.taskDao = taskDao;
liveResults = new LivePagedListBuilder<>(taskDao.tasksSortedByDate(),
new PagedList.Config.Builder() //
.setPageSize(20) //
.setPrefetchDistance(20) //
.setEnablePlaceholders(true) //
.build())
.setInitialLoadKey(0)
.build();
}
public LiveData<PagedList<Task>> getTasks() {
return liveResults;
}
}和
public class TaskFragment
extends Fragment {
RecyclerView recyclerView;
// ...
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
recyclerView = view.findViewById(R.id.recycler_view);
TaskViewModel viewModel = ViewModelProviders.of(this).get(TaskViewModel.class);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
final TaskAdapter taskAdapter = new TaskAdapter();
recyclerView.setAdapter(taskAdapter);
viewModel.getTasks().observe(this, pagedList -> {
//noinspection Convert2MethodRef
taskAdapter.submitList(pagedList);
});
}
@Override
protected void onDestroyView() {
super.onDestroyView();
viewModel.getTasks().removeObservers(this);
}
}和
public class TaskAdapter
extends PagedListAdapter<Task, TaskAdapter.ViewHolder> {
public TaskAdapter() {
super(Task.DIFF_CALLBACK);
}发布于 2018-06-29 18:05:14
如果你在房间中使用Rx,你可以使用Diff util或者List Adapter也有一个叫做SortedListAdapter的变体
提供来自开发人员android的示例实现
@Dao
interface UserDao {
@Query("SELECT * FROM user ORDER BY lastName ASC")
public abstract LiveData<List<User>> usersByLastName();
}
class MyViewModel extends ViewModel {
public final LiveData<List<User>> usersList;
public MyViewModel(UserDao userDao) {
usersList = userDao.usersByLastName();
}
}
class MyActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
MyViewModel viewModel = ViewModelProviders.of(this).get(MyViewModel.class);
RecyclerView recyclerView = findViewById(R.id.user_list);
UserAdapter<User> adapter = new UserAdapter();
viewModel.usersList.observe(this, list -> adapter.submitList(list));
recyclerView.setAdapter(adapter);
}
}
class UserAdapter extends ListAdapter<User, UserViewHolder> {
public UserAdapter() {
super(User.DIFF_CALLBACK);
}
@Override
public void onBindViewHolder(UserViewHolder holder, int position) {
holder.bindTo(getItem(position));
}
public static final DiffUtil.ItemCallback<User> DIFF_CALLBACK =
new DiffUtil.ItemCallback<User>() {
@Override
public boolean areItemsTheSame(
@NonNull User oldUser, @NonNull User newUser) {
// User properties may have changed if reloaded from the DB, but ID is fixed
return oldUser.getId() == newUser.getId();
}
@Override
public boolean areContentsTheSame(
@NonNull User oldUser, @NonNull User newUser) {
// NOTE: if you use equals, your object must properly override Object#equals()
// Incorrectly returning false here will result in too many animations.
return oldUser.equals(newUser);
}
}
}或者,您可以创建一个RXBus实现,在将数据插入数据库时,发布一个包含添加/删除数据的事件。订阅它,你就可以得到你想要的东西。
https://stackoverflow.com/questions/51098826
复制相似问题