Android 从 ViewModel 调用的 DataBinding 方法未在片段中使用 onClick 执行
Android DataBinding method called from ViewModel is not executed with onClick in fragment
我想用 onClick()
从我的 ViewModel
Class 调用一个方法,
但是调用没有被执行。否则,DataBinding 工作正常。
android:onClick="@{() -> ViewModel.test()}"
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/androidxmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="Project"
type="de.umr.studipro3000.model.Project" />
<variable
name="ViewModel"
type="de.umr.studipro3000.viewmodel.ProjectOverviewViewModel" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:background="?attr/selectableItemBackground"
android:onClick="@{() -> ViewModel.test()}"
android:padding="8dp">
<TextView
android:id="@+id/text_view_projectName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{Project.name}"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
</RelativeLayout>
</layout>
奇怪的是,这执行得很好。
android:onClick="@{() -> System.out.println(Project.name)}"
<data>
<variable
name="Project"
type="de.umr.studipro3000.model.Project" />
<variable
name="ViewModel"
type="de.umr.studipro3000.viewmodel.ProjectOverviewViewModel" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:background="?attr/selectableItemBackground"
android:onClick="@{() -> System.out.println(Project.name)}"
android:padding="8dp">
<TextView
android:id="@+id/text_view_projectName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{Project.name}"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
</RelativeLayout>
这是视图模型:
public class ProjectOverviewViewModel extends ViewModel {
private Repository repository;
private AuthService authService;
private MutableLiveData<List<Project>> projectsLiveData;
private String errorMessage;
private ProjectOverViewNavigator navigator;
public void setNavigator(ProjectOverViewNavigator navigator) {
this.navigator = navigator;
}
public ProjectOverviewViewModel() {
this.repository = Repository.getInstance();
this.authService = AuthService.getInstance();
this.errorMessage = "";
projectsLiveData = new MutableLiveData<>();
handleResponse(repository.projects((authService.currentToken.getValue())));
}
private void handleResponse(LiveData<ProjectListResponse> projectListResponseLiveData) {
projectListResponseLiveData.observeForever(
projectListResponse -> {
ProjectListSuccessResponse projectListSuccessResponse =
projectListResponse.getProjectListSuccessResponse();
if (projectListSuccessResponse != null) {
projectsLiveData.setValue(projectListSuccessResponse.getResult());
System.out.println(projectsLiveData.getValue().toString());
} else {
errorMessage = projectListResponse.getErrorResponse().getError();
}
});
}
public void itemClick(Project project) {
System.out.println("CLICKED");
navigator.onItemClick(project);
}
public void test(){
System.out.println("TEST");
}
public MutableLiveData<List<Project>> getProjectsLiveData() {
return projectsLiveData;
}
public void setProjectsLiveData(MutableLiveData<List<Project>> projectsLiveData) {
this.projectsLiveData = projectsLiveData;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}
这是我的片段
public class projectOverviewFragment extends Fragment implements ProjectOverViewNavigator {
private ProjectOverviewViewModel viewModel;
private ProjectAdapter adapter;
private FragmentProjectOverviewBinding binding;
private NavController navController;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = new ViewModelProvider(this).get(ProjectOverviewViewModel.class);
viewModel.setNavigator(this);
adapter = new ProjectAdapter();
}
@Nullable
@Override
public View onCreateView(
@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
binding = FragmentProjectOverviewBinding.inflate(inflater, container, false);
binding.setProjectOverviewViewModel(viewModel);
binding.setLifecycleOwner(this);
RecyclerView recyclerView = binding.recyclerViewProjects;
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
binding.getProjectOverviewViewModel().test();
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
navController = Navigation.findNavController(view);
viewModel
.getProjectsLiveData()
.observe(getViewLifecycleOwner(), projects -> adapter.setProjects(projects));
}
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.setting_menu, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
/*case R.id.first_action:
// your first action code
return true;
case R.id.second_action:
// your second action code
*/
return true;
}
@Override
public void onItemClick(Project project) {
System.out.println(project.getDescription());
/* projectOverviewFragmentDirections.ActionProjectOverviewFragmentToProjectDetailsFragment action =
projectOverviewFragmentDirections.actionProjectOverviewFragmentToProjectDetailsFragment(
project.getId());
navController.navigate(action);*/
}
}
我必须为项目适配器中的单个 Listitem 执行 Viewmodel 的数据绑定。 Fragment中设置了ProjectAdapter的VieModel。
public class ProjectAdapter extends RecyclerView.Adapter<ProjectAdapter.ProjectViewHolder> {
private ProjectOverviewViewModel viewModel;
public void setProjects(List<Project> projects) {
this.projects = projects;
notifyDataSetChanged();
}
public void setViewModel(ProjectOverviewViewModel viewModel) {
this.viewModel = viewModel;
}
public static class ProjectViewHolder extends RecyclerView.ViewHolder {
private ProjectItemBinding projectItemBinding;
public ProjectViewHolder(@NonNull ProjectItemBinding projectItemBinding) {
super(projectItemBinding.getRoot());
this.projectItemBinding = projectItemBinding;
}
}
private List<Project> projects = new ArrayList<>();
@NonNull
@Override
public ProjectViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
ProjectItemBinding projectItemBinding =
DataBindingUtil.inflate(
LayoutInflater.from(parent.getContext()), R.layout.project_item, parent, false);
return new ProjectViewHolder(projectItemBinding);
}
@Override
public void onBindViewHolder(@NonNull ProjectViewHolder holder, int position) {
Project currentProject = projects.get(position);
holder.projectItemBinding.setProject(currentProject);
holder.projectItemBinding.setProjectOverviewViewModel(viewModel);
}
@Override
public int getItemCount() {
return projects.size();
}
}
public View onCreateView(
@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
binding = FragmentProjectOverviewBinding.inflate(inflater, container, false);
binding.setLifecycleOwner(this);
binding.setProjectOverviewViewModel(viewModel);
RecyclerView recyclerView = binding.recyclerViewProjects;
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setHasFixedSize(true);
adapter.setViewModel(viewModel);
recyclerView.setAdapter(adapter);
return binding.getRoot();
}
我想用 onClick()
从我的 ViewModel
Class 调用一个方法,
但是调用没有被执行。否则,DataBinding 工作正常。
android:onClick="@{() -> ViewModel.test()}"
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/androidxmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="Project"
type="de.umr.studipro3000.model.Project" />
<variable
name="ViewModel"
type="de.umr.studipro3000.viewmodel.ProjectOverviewViewModel" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:background="?attr/selectableItemBackground"
android:onClick="@{() -> ViewModel.test()}"
android:padding="8dp">
<TextView
android:id="@+id/text_view_projectName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{Project.name}"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
</RelativeLayout>
</layout>
奇怪的是,这执行得很好。
android:onClick="@{() -> System.out.println(Project.name)}"
<data>
<variable
name="Project"
type="de.umr.studipro3000.model.Project" />
<variable
name="ViewModel"
type="de.umr.studipro3000.viewmodel.ProjectOverviewViewModel" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:background="?attr/selectableItemBackground"
android:onClick="@{() -> System.out.println(Project.name)}"
android:padding="8dp">
<TextView
android:id="@+id/text_view_projectName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{Project.name}"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
</RelativeLayout>
这是视图模型:
public class ProjectOverviewViewModel extends ViewModel {
private Repository repository;
private AuthService authService;
private MutableLiveData<List<Project>> projectsLiveData;
private String errorMessage;
private ProjectOverViewNavigator navigator;
public void setNavigator(ProjectOverViewNavigator navigator) {
this.navigator = navigator;
}
public ProjectOverviewViewModel() {
this.repository = Repository.getInstance();
this.authService = AuthService.getInstance();
this.errorMessage = "";
projectsLiveData = new MutableLiveData<>();
handleResponse(repository.projects((authService.currentToken.getValue())));
}
private void handleResponse(LiveData<ProjectListResponse> projectListResponseLiveData) {
projectListResponseLiveData.observeForever(
projectListResponse -> {
ProjectListSuccessResponse projectListSuccessResponse =
projectListResponse.getProjectListSuccessResponse();
if (projectListSuccessResponse != null) {
projectsLiveData.setValue(projectListSuccessResponse.getResult());
System.out.println(projectsLiveData.getValue().toString());
} else {
errorMessage = projectListResponse.getErrorResponse().getError();
}
});
}
public void itemClick(Project project) {
System.out.println("CLICKED");
navigator.onItemClick(project);
}
public void test(){
System.out.println("TEST");
}
public MutableLiveData<List<Project>> getProjectsLiveData() {
return projectsLiveData;
}
public void setProjectsLiveData(MutableLiveData<List<Project>> projectsLiveData) {
this.projectsLiveData = projectsLiveData;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}
这是我的片段
public class projectOverviewFragment extends Fragment implements ProjectOverViewNavigator {
private ProjectOverviewViewModel viewModel;
private ProjectAdapter adapter;
private FragmentProjectOverviewBinding binding;
private NavController navController;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = new ViewModelProvider(this).get(ProjectOverviewViewModel.class);
viewModel.setNavigator(this);
adapter = new ProjectAdapter();
}
@Nullable
@Override
public View onCreateView(
@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
binding = FragmentProjectOverviewBinding.inflate(inflater, container, false);
binding.setProjectOverviewViewModel(viewModel);
binding.setLifecycleOwner(this);
RecyclerView recyclerView = binding.recyclerViewProjects;
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
binding.getProjectOverviewViewModel().test();
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
navController = Navigation.findNavController(view);
viewModel
.getProjectsLiveData()
.observe(getViewLifecycleOwner(), projects -> adapter.setProjects(projects));
}
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.setting_menu, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
/*case R.id.first_action:
// your first action code
return true;
case R.id.second_action:
// your second action code
*/
return true;
}
@Override
public void onItemClick(Project project) {
System.out.println(project.getDescription());
/* projectOverviewFragmentDirections.ActionProjectOverviewFragmentToProjectDetailsFragment action =
projectOverviewFragmentDirections.actionProjectOverviewFragmentToProjectDetailsFragment(
project.getId());
navController.navigate(action);*/
}
}
我必须为项目适配器中的单个 Listitem 执行 Viewmodel 的数据绑定。 Fragment中设置了ProjectAdapter的VieModel。
public class ProjectAdapter extends RecyclerView.Adapter<ProjectAdapter.ProjectViewHolder> {
private ProjectOverviewViewModel viewModel;
public void setProjects(List<Project> projects) {
this.projects = projects;
notifyDataSetChanged();
}
public void setViewModel(ProjectOverviewViewModel viewModel) {
this.viewModel = viewModel;
}
public static class ProjectViewHolder extends RecyclerView.ViewHolder {
private ProjectItemBinding projectItemBinding;
public ProjectViewHolder(@NonNull ProjectItemBinding projectItemBinding) {
super(projectItemBinding.getRoot());
this.projectItemBinding = projectItemBinding;
}
}
private List<Project> projects = new ArrayList<>();
@NonNull
@Override
public ProjectViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
ProjectItemBinding projectItemBinding =
DataBindingUtil.inflate(
LayoutInflater.from(parent.getContext()), R.layout.project_item, parent, false);
return new ProjectViewHolder(projectItemBinding);
}
@Override
public void onBindViewHolder(@NonNull ProjectViewHolder holder, int position) {
Project currentProject = projects.get(position);
holder.projectItemBinding.setProject(currentProject);
holder.projectItemBinding.setProjectOverviewViewModel(viewModel);
}
@Override
public int getItemCount() {
return projects.size();
}
}
public View onCreateView(
@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
binding = FragmentProjectOverviewBinding.inflate(inflater, container, false);
binding.setLifecycleOwner(this);
binding.setProjectOverviewViewModel(viewModel);
RecyclerView recyclerView = binding.recyclerViewProjects;
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setHasFixedSize(true);
adapter.setViewModel(viewModel);
recyclerView.setAdapter(adapter);
return binding.getRoot();
}