从在 Android 的片段中实例化的 class 扩展 BottomSheetDialogFragment
Extend BottomSheetDialogFragment from a class instantiated in a fragment in Android
我有一个片段 (FragmentSearchResults),其中包含从数据库中检索到的结果,其中有一个按钮 "filters"。当用户点击这样的按钮时,将实例化扩展 BottomSheetDialogFragment 的 class (FiltersDialog),以便用户可以设置他的过滤器。当用户关闭 FiltersDialog activity 时,值从 FiltersDialog 传递到 FragmentSearchResults。
public class FragmentSearchResults extends Fragment implements FiltersDialog.FilterListener {
/* code */
ImageButton btnFilter = myFragment.findViewById(R.id.btn_filters);
btnFilter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showFilters();
}
});
}
private void showFilters() {
FiltersDialog filtersDialog = new FiltersDialog();
filtersDialog.show(((FragmentActivity) mContext).getSupportFragmentManager(), "argument");
}
@Override
public void onAttach(@NotNull Context context) {
super.onAttach(context);
mContext = context;
}
@Override
public void onFiltersSet(Map filters) {
// apply filters selected by user
}
public interface FilterListener {
void onFiltersSet(Map filters);
}
}
public class FiltersDialog extends BottomSheetDialogFragment {
private FilterListener mListener;
private Map<String, Object> mFilters;
public FiltersDialog() {
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.layout_filters_dialog, container, false);
TextView txtSave = v.findViewById(R.id.txt_save_filters);
mTxtSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onFiltersSet(mFilters);
}
});
return v;
}
public interface FilterListener {
void onFiltersSet(Map filters);
}
@Override
public void onAttach(@NotNull Context context) {
super.onAttach(context);
if (context instanceof FilterListener) {
mListener = (FilterListener) context;
}
else {
// Here's the error, as the activity Home.java containing FragmentSearchResults
// does not implement FilterListener, FragmentSearchResults does
throw new RuntimeException(context.toString() + " must implement FilterListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
}
问题是 FilterListener 需要在 FragmentSearchResults 中实现,但我传递的是 activity Home 上下文。
如何在片段中实现 FilterListener?
为什么不在 FiltersDialog
中创建方法,例如
public void setFiltersListener(FiltersDialog.FilterListener listener) {
mListener = listener;
}
并在实例化对话框后简单地调用它。
FiltersDialog filtersDialog = new FiltersDialog();
filtersDialog.setFiltersListener(this);
filtersDialog.show(((FragmentActivity) mContext).getSupportFragmentManager(), "argument");
然后就可以在dialog中使用listener了。像这样
if (mListener != null) {
mListener.onFiltersSet(mFilters);
}
How can I setup listener
to the dialog?
Fragment
中 onAttach
的参数是 FragmentHost(Activity). 因此,它不能类型转换为 FilterListener
.
我建议在 FragmentDialog
中实现 FilterListener
setter 的简单方法如下代码。
... in FiltersDialog
public void setListener(FilterListener listener) {
mListener = listener;
}
...
... in FragmentSearchResults
private void showFilters() {
FiltersDialog filtersDialog = new FiltersDialog();
filtersDialog.setListener(this);
filtersDialog.show(((FragmentActivity) mContext).getSupportFragmentManager(), "argument");
}
...
//When FragmentSearchResults recreated, FiltersDialog must also need to be recreated.
在这种情况下,更好的方法是使用 LiveData、ViewModel。使用共享 ViewModel 方法,可以通过位于其环境中的所有片段访问 Activity 级 ViewModel。
- 创建一个 Activity 关卡 ViewModel
- 在 ViewModel 中定义一个 LiveData
- 当您的 "FragmentSearchResults" 第一次打开时,开始
观察它。
- 当您打开 "FiltersDialog" 屏幕并单击保存按钮时,然后 post
到过滤器中的 LiveData 更改(您在此处有 activity 上下文,
您可以在此处获取 ActivityViewModel,从中获取 LiveData,post
对此 LiveData 的更改)
- Now As "FragmentSearchResults" 已经在观察
LiveData,你会在这里得到回调,做出相应的改变。这样你的代码就会完全解耦。你会从
接口的喧嚣。
我有一个片段 (FragmentSearchResults),其中包含从数据库中检索到的结果,其中有一个按钮 "filters"。当用户点击这样的按钮时,将实例化扩展 BottomSheetDialogFragment 的 class (FiltersDialog),以便用户可以设置他的过滤器。当用户关闭 FiltersDialog activity 时,值从 FiltersDialog 传递到 FragmentSearchResults。
public class FragmentSearchResults extends Fragment implements FiltersDialog.FilterListener {
/* code */
ImageButton btnFilter = myFragment.findViewById(R.id.btn_filters);
btnFilter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showFilters();
}
});
}
private void showFilters() {
FiltersDialog filtersDialog = new FiltersDialog();
filtersDialog.show(((FragmentActivity) mContext).getSupportFragmentManager(), "argument");
}
@Override
public void onAttach(@NotNull Context context) {
super.onAttach(context);
mContext = context;
}
@Override
public void onFiltersSet(Map filters) {
// apply filters selected by user
}
public interface FilterListener {
void onFiltersSet(Map filters);
}
}
public class FiltersDialog extends BottomSheetDialogFragment {
private FilterListener mListener;
private Map<String, Object> mFilters;
public FiltersDialog() {
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.layout_filters_dialog, container, false);
TextView txtSave = v.findViewById(R.id.txt_save_filters);
mTxtSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onFiltersSet(mFilters);
}
});
return v;
}
public interface FilterListener {
void onFiltersSet(Map filters);
}
@Override
public void onAttach(@NotNull Context context) {
super.onAttach(context);
if (context instanceof FilterListener) {
mListener = (FilterListener) context;
}
else {
// Here's the error, as the activity Home.java containing FragmentSearchResults
// does not implement FilterListener, FragmentSearchResults does
throw new RuntimeException(context.toString() + " must implement FilterListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
}
问题是 FilterListener 需要在 FragmentSearchResults 中实现,但我传递的是 activity Home 上下文。
如何在片段中实现 FilterListener?
为什么不在 FiltersDialog
中创建方法,例如
public void setFiltersListener(FiltersDialog.FilterListener listener) {
mListener = listener;
}
并在实例化对话框后简单地调用它。
FiltersDialog filtersDialog = new FiltersDialog();
filtersDialog.setFiltersListener(this);
filtersDialog.show(((FragmentActivity) mContext).getSupportFragmentManager(), "argument");
然后就可以在dialog中使用listener了。像这样
if (mListener != null) {
mListener.onFiltersSet(mFilters);
}
How can I setup
listener
to the dialog?
Fragment
中 onAttach
的参数是 FragmentHost(Activity). 因此,它不能类型转换为 FilterListener
.
我建议在 FragmentDialog
中实现 FilterListener
setter 的简单方法如下代码。
... in FiltersDialog
public void setListener(FilterListener listener) {
mListener = listener;
}
...
... in FragmentSearchResults
private void showFilters() {
FiltersDialog filtersDialog = new FiltersDialog();
filtersDialog.setListener(this);
filtersDialog.show(((FragmentActivity) mContext).getSupportFragmentManager(), "argument");
}
...
//When FragmentSearchResults recreated, FiltersDialog must also need to be recreated.
在这种情况下,更好的方法是使用 LiveData、ViewModel。使用共享 ViewModel 方法,可以通过位于其环境中的所有片段访问 Activity 级 ViewModel。
- 创建一个 Activity 关卡 ViewModel
- 在 ViewModel 中定义一个 LiveData
- 当您的 "FragmentSearchResults" 第一次打开时,开始 观察它。
- 当您打开 "FiltersDialog" 屏幕并单击保存按钮时,然后 post 到过滤器中的 LiveData 更改(您在此处有 activity 上下文, 您可以在此处获取 ActivityViewModel,从中获取 LiveData,post 对此 LiveData 的更改)
- Now As "FragmentSearchResults" 已经在观察 LiveData,你会在这里得到回调,做出相应的改变。这样你的代码就会完全解耦。你会从 接口的喧嚣。