这非常奇怪且难以解释,因此屏幕截图可能会有所帮助。
我有一个
Fragment
,它启动 DialogFragment
来过滤 RecyclerView
的结果。该对话框显示用户可以选中或取消选中的三个选项。
如果用户通过点击后退按钮或触摸对话框外部来取消对话框,我想恢复用户所做的选择,因此选项将像对话框打开时一样被选中或取消选中。
为了实现这一目标,我将应用于
RecyclerView
的当前过滤器保留在 boolean
中的 test
数组 (Fragment
) 中。因此,我覆盖了 onCancel()
的 DialogFragment
方法来调用 Fragment
中的另一个方法,该方法再次将当前过滤器设置为 DialogFragment
的实例。
我遇到的问题是,用户第二次打开对话框并取消它时,我的
Fragment
数组中位于未选中/选中选项位置的布尔对象会更改值。
默认情况下,所有选项均已选中:
然后用户取消选中一个选项,但不单击接受:
当用户对对话框选项进行了更改但没有应用它们时,我恢复了更改。 Logcat 显示再次应用相同过滤器之前和之后的值:
2024-01-18 20:37:33.205 31320-31320 过滤器
com.example.futbol D 调用 setSeleccion 之前测试数组的值:[true, 真的,真的]2024-01-18 20:37:33.206 31320-31320 过滤器
com.example.futbol D 调用 setSeleccion 后测试数组的值:[true, 真的,真的]
然后,用户再次打开对话框,正如预期的那样,所有选项都被选中。到目前为止,一切顺利:
现在用户取消选中另一个选项,并且像以前一样,不接受:
但是,当我检查日志时,我看到
test
数组甚至在调用 setSeleccion()
之前就已更改:
2024-01-18 20:41:14.832 31320-31320 过滤器
com.example.futbol D 调用前测试数组的值 setSeleccion:[真,真,假]2024-01-18 20:41:14.832 31320-31320 过滤器
com.example.futbol D 调用后测试数组的值 setSeleccion:[真,真,假]
确实,如果用户再次打开对话框,则上次未选中的选项将被取消选中:
在我的代码中,
test
数组仅使用两次,一次用于声明它,第二次作为setSeleccion()
的参数。
我的
Fragment
代码(我删除了不相关的行):
public class ListaFragment extends BaseTemporadaFragment
implements Adaptador.OnEventClickListener,
FiltroFragment.FiltroListener {
public static final String TAG = "ListaFragment";
private boolean[] test = new boolean[]{true, true, true};
private FiltroFragment dialogFragment;
public ListaFragment() {
}
public static ListaFragment newInstance(int temporada, boolean[] filtros) {
ListaFragment fragment = new ListaFragment();
Bundle args = new Bundle();
args.putInt("temporada", temporada);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.dialogFragment = new FiltroFragment();
this.dialogFragment.setListener(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_lista, container, false);
((AppCompatActivity) this.getActivity()).getSupportActionBar()
.setTitle(R.string.ver_lista);
this.setHasOptionsMenu(true);
return v;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
}
// TODO
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.filtro, menu);
super.onCreateOptionsMenu(menu, inflater);
}
// TODO
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == R.id.menu_filtro) {
this.dialogFragment.show(MainActivity.fragmentManager, FiltroFragment.TAG);
}
return super.onOptionsItemSelected(item);
}
@Override
public void onDialogPositiveClick(DialogFragment dialog) {
}
@Override
public void OnCancelListener(DialogFragment dialog) {
Log.d("Filters", "Values of test array before calling setSeleccion: " + Arrays.toString(this.test));
this.dialogFragment.setSeleccion(this.test);
Log.d("Filters", "Values of test array after calling setSeleccion: " + Arrays.toString(this.test));
}
@Override
public void onClick(View view) {
}
// TODO
@Override
public void onItemClick(Partido partido) {
}
}
我的
DialogFragment
:
public class FiltroFragment extends DialogFragment {
public interface FiltroListener {
public void onDialogPositiveClick(DialogFragment dialog);
public void OnCancelListener(DialogFragment dialog);
}
private FiltroListener listener;
public static final String[] TIPOS = new String[]{"Liga", "Copa", "Amistosos"};
private boolean[] seleccion = new boolean[]{true, true, true};
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
builder.setTitle(this.getResources().getString(R.string.titulo));
builder.setMultiChoiceItems(FiltroFragment.TIPOS, this.seleccion,
new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i, boolean b) {
//cambiarSeleccion(i, b);
}
});
builder.setPositiveButton(R.string.aplicar,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
listener.onDialogPositiveClick(FiltroFragment.this);
});
return builder.create();
}
@Override
public void onCancel(@NonNull DialogInterface dialog) {
super.onCancel(dialog);
listener.OnCancelListener(FiltroFragment.this);
}
public boolean[] getSeleccion() {
return this.seleccion;
}
public void setSeleccion(boolean[] seleccion) {
this.seleccion = seleccion;
}
public void setListener(FiltroListener listener) {
this.listener = listener;
}
}
正如您所看到的,我的
setSeleccion()
方法只是更改了对话框的布尔数组,但它不会修改 test
数组。
我还尝试调试我的应用程序在
test
数组的值更改时中断,但它没有中断!!!
test
数组怎么可能改变值?
我相当确定这就是你解释这种行为的方式:
您打开对话框,修改它,取消它,在
OnCancelListener
中调用 this.dialogFragment.setSeleccion(this.test)
,此时您的对话框现在引用了 test
变量。
您再次打开对话框,一切看起来都很好(因为 test =
[true, true, true]
)。
您取消选中其中一个选项,更改
DialogFragment.seleccion
AND 的值 ListaFragment.test
的值(因为它是对同一数组的引用)。