上下文:我有一个User
类,看起来像这样:
public class User {
private String firstname;
private String lastname;
private GeoPoint location;
/* Constructor and getters */
...
}
还有两个片段
s,在其中我将使用RecyclerView
和GoogleMap
在第一个片段中显示用户名列表,后者显示第二个片段中用户的设备位置标记。我在这两个片段之间使用共享的ViewModel
,以提供所需的数据。ViewModel
如下所示:
@HiltViewModel
public class UsersViewModel extends ViewModel {
private List<User> users;
private UserRepository repository;
@Inject
public UsersViewModel(UserRepository repository) {
this.repository = repository;
}
public void fetchUsers(OnFetchDataCallback callback) {
repository.getUsers(callback);
}
public void setUsers(List<User> users) {
this.users = users;
}
public List<User> getUsers() {
return users;
}
}
在我的资源库课上,
public class UserRepository {
private final FirebaseFirestore db;
@Inject
public UserRepository(FirebaseFirestore db) {
this.db = db;
}
public List<User> getUsers(OnFetchDataCallback callback) {
db.collection("users")
.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot val,
@FirebaseFirestoreException e) {
List<User> users = new ArrayList<>();
for (QueryDocumentSnapshot document : val) {
users.add(document.toObject(User.class);
}
callback.onFetchData(users);
}
});
}
}
我有一个名为getUsers()
的方法,可以从firestore数据库中实际获取用户。我还创建了一个如下所示的接口回调
public interface OnFetchDataCallback {
void onFetchData(List<User> users);
}
这样以后我就可以在我的两个片段中访问获取的用户。在我的第一个片段中,
@AndroidEntryPoint
public class DisplayUsersFragment extends Fragment {
private FragmentDisplayUsersBinding binding;
private UsersViewModel viewModel;
private UsersAdapter adapter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = new ViewModelProvider(this).get(UsersViewModel.class);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
binding = FragmentDisplayUsersBinding.inflate(inflater, container, false);
binding.usersRecyclerView.setLayoutManager(
new LinearLayoutManager(getContext()));
viewModel.fetchUsers(new OnFetchDataCallback() {
@Override
public void onFetchData(List<User> users) {
viewModel.setUsers(users);
adapter = new UsersAdapter(viewModel.getUsers());
binding.usersRecyclerView.setAdapter(adapter);
}
});
return binding.getRoot();
}
}
我调用了fetchUsers()
,访问了回调中users
的列表,并将其设置为my
viewModel
的users
,然后为myRecyclerView
构建了一个适配器,并通过调用viewModel>为其提供了所需的数据。getUsers()
并将其作为适配器的构造函数参数传递。现在,我的问题是,在我的第二个片段中,
@AndroidEntryPoint
public class UsersMapFragment extends Fragment implements OnMapReadyCallback {
private FragmentUsersMapBinding binding;
private UsersViewModel viewModel;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = new ViewModelProvider(this).get(UsersViewModel.class);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
binding = FragmentUsersMapBinding.inflate(inflater, container, false);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view,
@Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SupportMapFragment mapFragment = SupportMapFragment.newInstance();
getChildFragmentManager().beginTransaction()
.add(R.id.users_map_fragment_container, mapFragment)
.commit()
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(@NonNull GoogleMap googleMap) {
viewModel.fetchUsers(new OnFetchDataCallback() {
@Override
public void onFetchData(List<User> users) {
viewModel.setUsers(users);
for (User user : viewModel.getUsers()) {
googleMap.addMarker(new MarkerOptions()
.position(new LatLng(
user.getLocation().getLatitude(),
user.getLocation().getLongitude())
)
.title(user.getFirstname() + " "
user.getLastname()
)
);
}
}
});
}
}
我再次调用了
fetchUser()
内部onMap就绪()
,以便我可以访问其回调内部的用户,并使用它们在映射中创建标记。本质上,我尝试调用fetchUser()
两次,但我认为有一种更有效的方法可以做到这一点,但我不知道如何处理。请帮帮我,对不起,我的英语不好。
您可以在ViewModel中使用实时数据:请参阅下面给出的代码:
@HiltViewModel
public class UsersViewModel extends ViewModel {
private List<User> users;
MutableLiveData<List<User>> usersLiveData = new MutableLiveData();
private UserRepository repository;
@Inject
public UsersViewModel(UserRepository repository) {
this.repository = repository;
}
public void fetchUsers() {
repository.getUsers(new OnFetchDataCallback() {
@Override
public void onFetchData(List<User> users) {
usersLiveData.setValue(users);
// you can observe this data after calling fetch users from your activity
setUsers(users);
});
}
public void setUsers(List<User> users) {
this.users = users;
}
public List<User> getUsers() {
return users;
}
}
在活动中:
mViewModel.fetchUsers();
在这两个片段中:
viewModel.usersLiveData.observe(this,{ list->
// user your list here in both fragments
// rather than fetch users on both fragments
});
好吧,正如我试图在标题中总结的那样,下面是细节。 我们有一个相对较大的应用程序,它使用Dagger,以非常不理想的方式,所以我们决定开始编写测试,为此,我需要公开Mockito的依赖项,因此,我面临一个问题,开始使用单例工厂提供视图模型,仍然适用,并且有大量的教程可以解释这一点。 在我们的应用程序中,有许多使用单个活动实现的功能和导航组件,该单个活动有时具有创建的视图模型,我们使用该模型在容器活动
在上一次谷歌IO上,谷歌发布了一些新arch组件的预览,其中之一是ViewModel。 在文档中,谷歌展示了该组件的一个可能用途: 一个活动中的两个或多个片段需要相互通信是很常见的。这绝不是小事,因为两个片段都需要定义一些接口描述,所有者活动必须将两者绑定在一起。此外,两个片段都必须处理另一个片段尚未创建或不可见的情况。 这个常见的痛点可以通过使用ViewModel对象来解决。想象一个主细节片段的
我有一个包含两个片段的FragmentActivity(support-v4)。并且都包含一个带有ActionBar的SearchView的菜单。 PlayListFragment: 附注。 我找到了原因,但没有解决方法: 呼叫 如何禁用ActionBar/SearchView/TextView的保存和还原?
我需要观察Modelview中的livedata更改来更新片段(将列表添加到RecycerView中)。 该实现工作正常,但在片段之间切换时面临问题。 并试图将观察者移除为:或或或尝试在
我有一个包含一个活动和两个片段的应用程序,在第一个片段中,我应该能够将数据插入数据库,在第二个片段中,我应该能够在一个RecyclerView中看到添加的项目。 所以我已经创建了数据库、我的RecyclerView适配器和ViewModel, 我是否应该在活动中初始化ViewModel,并以某种方式从片段中调用它来使用insert? 我是否应该在两个片段中初始化viewmodel两次? 我的代码如
问题内容: 我的GUI中有多个组合框,所有组合框都需要数据。此数据将随机更改,因此需要一种快速的方法来保持所有值同步。我遇到了DefaultComboBoxModel,它实际上非常合适。唯一的事情是,我需要组合框彼此独立- 意思是:如果我在一个上选择一个值,则所有其他框都不应更改。我做了一些研究,并阅读了标准的Java教程,但没有一个告诉我如何使用DefaultComboBoxModel来实现这一