片段之间的共享数据(父和子列表视图)
Shared data between fragment (parent and child listviews)
我在 fragment
中实现了 listview
(下面有详细说明),我不确定是否有更好的方法。任何人都可以看到我的方法,并向我建议在没有代码混乱的情况下实现它的最佳方法是什么。另外,附上所需结果的 gif 动画。
我想做的是,当用户点击详细搜索时,用户将看到一个类别列表,每个类别都有一个子类别,每个类别中可以勾选多个项目。用户返回 main fragment
后,他将在主 fragment
中选择可用的项目。然后根据用户选择的数据,我可以 运行 搜索查询。
想要的结果
过滤片段
public class FilterFragment extends Fragment {
private GalleryViewModel galleryViewModel;
private ListView lv;
private List<Cats> categoryList;
private String[]
groupArray = {"Category1", "Category2", "Category3"};
private String[][] childArray = {{"Test1", "Test2", "Test3"},
{"Video1", "Video2", "Video3"}, {"Audio1", "Audio2", "Audio3"}};
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_gallery, container, false);
lv = (ListView) root.findViewById(R.id.list_view);
List<Cats> categoryData = null;
if(getArguments()!=null){
// data = (String[]) getArguments().getSerializable("strArray");
categoryList = (List<Cats>) getArguments().getSerializable("CATEGORY_LIST");
}
AdapterView.OnItemClickListener clickListener = null;
// If no data received means this is the first activity
if (categoryData == null) {
categoryData = categoryList;
clickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
FilterFragment newFragment = new FilterFragment();
Bundle bundle = new Bundle();
bundle.putSerializable("strArray", childArray[position]);
newFragment.setArguments(bundle);
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.nav_host_fragment, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
};
}
// get data from the table by the ListAdapter
ListAdapter customAdapter = new ListAdapter(getContext(), R.layout.fragment_filter_item_row, categoryData);
lv.setAdapter(customAdapter);
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(clickListener);
return root;
}
}
我将通过 bundles
将选定的条目取回 main fragment
。
您需要一个自定义适配器,这很容易理解
在您的片段中创建一个列表
public List<Cats> selectedData = new ArrayList<>();
在你的适配器中传递你片段的引用
YourFragment fragment;
List<Cats> categoryData;
public YourAdapter(YourFragment fragmet, List<Cats> categoryData){
this.fragment = fragment;
this.categoryData = categoryData;
}
在你的适配器里面 onBindViewHolder
public void onBindViewHolder(@NonNull ViewHolder holder, int position){
holder.checkbox.setOnCheckedChangeListener((buttonView, isChecked) -> {
if(isChecked)
fragment.selectedData.add(categoryData.get(position));
});
}
好的,我终于找到了解决方案。我的方法是在片段中使用 sharedViewModel。
使用 SharedViewModel,我们可以在片段之间进行通信。如果我们考虑两个片段,两个片段都可以通过它们的 activity 访问 ViewModel。这是一个预览,我已经上传了一个演示应用程序和代码到 github 这样每个人都可以访问并能够修改片段。
SharedViewModel
public class SharedViewModel extends ViewModel {
private MutableLiveData<CharSequence> text = new MutableLiveData<>();
public void setText(CharSequence input) {
text.setValue(input);
}
public LiveData<CharSequence> getText() {
return text;
}
}
获取 Fragment 中的 sharedViewModel 数据
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
viewModel = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
viewModel.getText().observe(getViewLifecycleOwner(), new Observer<CharSequence>() {
@Override
public void onChanged(@Nullable CharSequence charSequence) {
editText.setText(charSequence);
}
});
}
以上是简化的概念,您可以根据需要进行修改。完整代码请参考github
我在 fragment
中实现了 listview
(下面有详细说明),我不确定是否有更好的方法。任何人都可以看到我的方法,并向我建议在没有代码混乱的情况下实现它的最佳方法是什么。另外,附上所需结果的 gif 动画。
我想做的是,当用户点击详细搜索时,用户将看到一个类别列表,每个类别都有一个子类别,每个类别中可以勾选多个项目。用户返回 main fragment
后,他将在主 fragment
中选择可用的项目。然后根据用户选择的数据,我可以 运行 搜索查询。
想要的结果
过滤片段
public class FilterFragment extends Fragment {
private GalleryViewModel galleryViewModel;
private ListView lv;
private List<Cats> categoryList;
private String[]
groupArray = {"Category1", "Category2", "Category3"};
private String[][] childArray = {{"Test1", "Test2", "Test3"},
{"Video1", "Video2", "Video3"}, {"Audio1", "Audio2", "Audio3"}};
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_gallery, container, false);
lv = (ListView) root.findViewById(R.id.list_view);
List<Cats> categoryData = null;
if(getArguments()!=null){
// data = (String[]) getArguments().getSerializable("strArray");
categoryList = (List<Cats>) getArguments().getSerializable("CATEGORY_LIST");
}
AdapterView.OnItemClickListener clickListener = null;
// If no data received means this is the first activity
if (categoryData == null) {
categoryData = categoryList;
clickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
FilterFragment newFragment = new FilterFragment();
Bundle bundle = new Bundle();
bundle.putSerializable("strArray", childArray[position]);
newFragment.setArguments(bundle);
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.nav_host_fragment, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
};
}
// get data from the table by the ListAdapter
ListAdapter customAdapter = new ListAdapter(getContext(), R.layout.fragment_filter_item_row, categoryData);
lv.setAdapter(customAdapter);
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(clickListener);
return root;
}
}
我将通过 bundles
将选定的条目取回 main fragment
。
您需要一个自定义适配器,这很容易理解
在您的片段中创建一个列表
public List<Cats> selectedData = new ArrayList<>();
在你的适配器中传递你片段的引用
YourFragment fragment;
List<Cats> categoryData;
public YourAdapter(YourFragment fragmet, List<Cats> categoryData){
this.fragment = fragment;
this.categoryData = categoryData;
}
在你的适配器里面 onBindViewHolder
public void onBindViewHolder(@NonNull ViewHolder holder, int position){
holder.checkbox.setOnCheckedChangeListener((buttonView, isChecked) -> {
if(isChecked)
fragment.selectedData.add(categoryData.get(position));
});
}
好的,我终于找到了解决方案。我的方法是在片段中使用 sharedViewModel。
使用 SharedViewModel,我们可以在片段之间进行通信。如果我们考虑两个片段,两个片段都可以通过它们的 activity 访问 ViewModel。这是一个预览,我已经上传了一个演示应用程序和代码到 github 这样每个人都可以访问并能够修改片段。
SharedViewModel
public class SharedViewModel extends ViewModel {
private MutableLiveData<CharSequence> text = new MutableLiveData<>();
public void setText(CharSequence input) {
text.setValue(input);
}
public LiveData<CharSequence> getText() {
return text;
}
}
获取 Fragment 中的 sharedViewModel 数据
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
viewModel = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
viewModel.getText().observe(getViewLifecycleOwner(), new Observer<CharSequence>() {
@Override
public void onChanged(@Nullable CharSequence charSequence) {
editText.setText(charSequence);
}
});
}
以上是简化的概念,您可以根据需要进行修改。完整代码请参考github