It's ok to have multiple different data flow in one screen.
On the one hand we can talk about changing user roles list without changing user itself on the other hand user name can be changed without updating roles list. Addition benefit of using multiple data flow, you can show user data while loading user roles.
I suppose, you have pojo of user and roles to avoid synchronization issues. You can implement smooth data delivering (from db to view) like in sample below:
View model
public class UserRolesViewModel extends ViewModel {
private final MutableLiveData<Integer> mSelectedUser;
private final LiveData<UsersEntity> mUserData;
private final LiveData<List<RolesEntity>> mRolesData;
private DataBase mDatabase;
public UserRolesViewModel() {
mSelectedUser = new MutableLiveData<>();
// create data flow for user and roles synchronized by mSelectedUser
mUserData = Transformations.switchMap(mSelectedUser, mDatabase.getUserDao()::getUser);
mRolesData = Transformations.switchMap(mSelectedUser, mDatabase.getRolesDao()::getUserRoles);
}
public void setDatabase(DataBase dataBase) {
mDatabase = dataBase;
}
@MainThread
public void setSelectedUser(Integer userId) {
if (mDatabase == null)
throw new IllegalStateException("You need setup database before select user");
mSelectedUser.setValue(userId);
}
public LiveData<UsersEntity> getUserData() {
return mUserData;
}
public LiveData<List<RolesEntity>> getRolesData() {
return mRolesData;
}
}
It's better to encapsulate data source implementation in Repository
class and inject it via DI like in this paragraph.
Database sample based on Many-to-Many paragraph from this article
Entities
Users
@Entity(tableName = "users")
public class UsersEntity {
@PrimaryKey
public int id;
public String name;
}
Roles
@Entity(tableName = "roles")
public class RolesEntity {
@PrimaryKey
public int id;
public String name;
}
User roles
This entity require special attention because we need to declare foreign keys to make joun operations futire
@Entity(tableName = "user_roles", primaryKeys = {"user_id", "role_id"}, foreignKeys = {
@ForeignKey(entity = UsersEntity.class, parentColumns = "id", childColumns = "user_id"),
@ForeignKey(entity = RolesEntity.class, parentColumns = "id", childColumns = "role_id")
})
public class UserRolesEntity {
@ColumnInfo(name = "user_id")
public int userId;
@ColumnInfo(name = "role_id")
public int roleId;
}
Dao
Users dao
@Dao
public interface UserDao {
@Query("SELECT * from users WHERE id = :userId")
LiveData<UsersEntity> getUser(int userId);
}
Roles dao
@Dao
public interface RolesDao {
@Query("SELECT * FROM roles INNER JOIN user_roles ON roles.id=user_roles.role_id WHERE user_roles.user_id = :userId")
LiveData<List<RolesEntity>> getUserRoles(int userId);
}
Data base
@Database(entities = {UsersEntity.class, RolesEntity.class, UserRolesEntity.class}, version = 1)
public abstract class DataBase extends RoomDatabase {
public abstract UserDao getUserDao();
public abstract RolesDao getRolesDao();
}